mirror of https://github.com/OpenVPN/openvpn-gui
import of openvpn-gui-1.0.3.zip
git-svn-id: https://openvpn-gui.svn.sourceforge.net/svnroot/openvpn-gui/trunk@2 43a1345a-9c20-4331-951f-9845fc178312pull/1/head
parent
a0e7f98401
commit
fd9e4ae6db
|
@ -0,0 +1,14 @@
|
|||
OpenVPN GUI -- A Windows GUI for OpenVPN
|
||||
|
||||
Copyright (C) 2004-2005 by Mathias Sundman <info@openvpn.se>
|
||||
|
||||
|
||||
OpenVPN GUI is distributed under GPL license.
|
||||
(see COPYRIGHT.GPL)
|
||||
|
||||
Parts of the source code for OpenVPN GUI is taken from
|
||||
openvpnserv.c included with the OpenVPN [1] distribution.
|
||||
|
||||
[1] OpenVPN is copyrighted by OpenVPN Solutions LLC <info@openvpn.net>,
|
||||
and distributed under GPL license.
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 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.
|
|
@ -0,0 +1,44 @@
|
|||
# This makefile builds OpenVPN-GUI using the mingw environment.
|
||||
|
||||
OPENSSL = /c/OpenSSL
|
||||
|
||||
RES_LANG = en
|
||||
GUI_VERSION = 1.0.3
|
||||
|
||||
EXE = openvpn-gui-$(GUI_VERSION)-$(RES_LANG).exe
|
||||
|
||||
HEADERS = main.h openvpn.h openvpn_monitor_process.h tray.h viewlog.h \
|
||||
service.h options.h passphrase.h openvpn-gui-res.h proxy.h \
|
||||
ieproxy.h registry.h openvpn_config.h chartable.h scripts.h
|
||||
|
||||
OBJS = main.o tray.o openvpn.o openvpn_monitor_process.o viewlog.o \
|
||||
service.o options.o passphrase.o proxy.o ieproxy.o registry.o \
|
||||
openvpn_config.o scripts.o openvpn-gui-$(RES_LANG).res
|
||||
|
||||
INCLUDE_DIRS = -I. -I${OPENSSL}/include
|
||||
LIB_DIRS = -L${OPENSSL}/lib/MinGW
|
||||
|
||||
WARNS = -W -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast \
|
||||
-Wcast-align -Wwrite-strings -Wconversion -Wsign-compare \
|
||||
-Waggregate-return -Wmissing-noreturn -Wmissing-format-attribute \
|
||||
-Wredundant-decls -Winline -Wdisabled-optimization \
|
||||
-Wno-unused-function -Wno-unused-variable
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -g -O2 ${WARNS} -mno-cygwin
|
||||
LDFLAGS = -mwindows -s
|
||||
#LDFLAGS = -mwindows
|
||||
WINDRES = windres.exe
|
||||
|
||||
all : ${OBJS}
|
||||
${CC} -o ${EXE} ${OBJS} ${LIB_DIRS} -leay32 -lWinInet ${LDFLAGS}
|
||||
# ${CC} -o ${EXE} ${OBJS} ${LIB_DIRS} -lWinInet ${LDFLAGS}
|
||||
|
||||
clean :
|
||||
rm -f *.o *.exe *.res
|
||||
|
||||
%.o : %.c ${HEADERS}
|
||||
${CC} ${CFLAGS} ${INCLUDE_DIRS} -c $< -o $@
|
||||
|
||||
openvpn-gui-$(RES_LANG).res : openvpn-gui-$(RES_LANG).rc openvpn-gui-res.h
|
||||
$(WINDRES) -i openvpn-gui-$(RES_LANG).rc -I rc -o openvpn-gui-$(RES_LANG).res -O coff
|
|
@ -0,0 +1,231 @@
|
|||
Installation Instructions for OpenVPN GUI for Windows
|
||||
-----------------------------------------------------
|
||||
|
||||
You can either get my installation package for OpenVPN 2.0.X where I've
|
||||
bundled the gui in the installation package, or you can use the original
|
||||
installation package from OpenVPN, and then manually install OpenVPN GUI.
|
||||
|
||||
|
||||
Installation using the bundled OpenVPN package with OpenVPN GUI included
|
||||
------------------------------------------------------------------------
|
||||
|
||||
* Download openvpn-2.0.X-gui-1.0.X-install.exe from
|
||||
http://openvpn.se
|
||||
|
||||
* If you have a previous version of OpenVPN GUI installed, shut it down.
|
||||
Make sure it's closed by ALL logged on users.
|
||||
|
||||
* Run the install program. During the installation you can choose if the GUI
|
||||
should be started automatically at system startup. The default is yes.
|
||||
|
||||
* Create a xxxx.ovpn config-file with your favorite texteditor and save it in:
|
||||
C:\Program files\OpenVPN\config\. You should NOT use the "log" or "log-append"
|
||||
options as OpenVPN GUI redirect the normal output to a log file itself.
|
||||
There is a sample config files in the "sample-config" folder. Please
|
||||
refer to the OpenVPN project homepage for more information regarding
|
||||
creating the configuration file. http://openvpn.net/
|
||||
|
||||
|
||||
Manual installation of OpenVPN GUI
|
||||
----------------------------------
|
||||
|
||||
* Download and install OpenVPN from http://openvpn.net/
|
||||
|
||||
* Download openvpn-gui-1.0.X.exe and save it in OpenVPN's bin folder.
|
||||
Default is "C:\Program Files\OpenVPN\bin\". You must put it in this folder
|
||||
because OpenVPN GUI depends on the OpenSSL DLLs installed in this folder by
|
||||
OpenVPN.
|
||||
|
||||
* Create a xxxx.ovpn config-file with your favorite texteditor and save it in:
|
||||
C:\Program files\OpenVPN\config\. You should NOT use the "log" or "log-append"
|
||||
options as OpenVPN GUI redirect the normal output to a log file itself.
|
||||
There is a sample config files in the "sample-config" folder. Please
|
||||
refer to the OpenVPN project homepage for more information regarding
|
||||
creating the configuration file. http://openvpn.net/
|
||||
|
||||
* Put a short-cut to openvpn-gui-1.0-X.exe in your
|
||||
"Start->All Program->StartUp" folder if you want the gui started automatically
|
||||
when you logon to Windows.
|
||||
|
||||
* Start the GUI by double-clicking the openvpn-gui-1.0.X.exe file.
|
||||
|
||||
*** You need to be Administrator the first time you run OpenVPN GUI for it to
|
||||
create its registry keys. After that you don't have to be administrator
|
||||
just to run the GUI, however OpenVPN requires the user to be
|
||||
administrator to run! ***
|
||||
|
||||
|
||||
Using OpenVPN GUI
|
||||
-----------------
|
||||
|
||||
When OpenVPN GUI is started your config folder (C:\Program Files\OpenVPN\config)
|
||||
will be scanned for .ovpn files, and an icon will be displayed in the taskbar's
|
||||
status area.
|
||||
|
||||
If you do not have any openvpn connection running, the config dir will be
|
||||
re-scanned for new config files every time you open the OpenVPN GUI menu by
|
||||
right-clicking the icon.
|
||||
|
||||
When you choose to connect to a site OpenVPN GUI will launch openvpn with
|
||||
the specified config file. If you use a passphrase protected key you will be
|
||||
prompted for the passphrase.
|
||||
|
||||
If you want OpenVPN GUI to start a connection automatically when it's started,
|
||||
you can use the --connect cmd-line option. You have to include the extention
|
||||
for the config file. Example:
|
||||
|
||||
openvpn-gui --connect office.ovpn
|
||||
|
||||
|
||||
Run OpenVPN GUI as a Non-Admin user
|
||||
-----------------------------------
|
||||
|
||||
OpenVPN currently does not work as a normal (non-admin) user. OpenVPN GUI
|
||||
2.0 will solve this by using an enhanced version of the OpenVPN service
|
||||
to start and stop openvpn processes.
|
||||
|
||||
In the mean time, it is possible to use OpenVPN GUI to control the current
|
||||
OpenVPN Service to start and stop a connection.
|
||||
|
||||
To use OpenVPN GUI to control the OpenVPN service, set the registry value
|
||||
"service_only" to '1'. See the section about registry values below.
|
||||
|
||||
Limitations with this way:
|
||||
|
||||
There is no way for OpenVPN GUI ta hand over a password to the service
|
||||
wrapper, so you can't use passphrase protected private keys or
|
||||
username/password authentication.
|
||||
|
||||
If you have multiple openvpn configurations, all will be started and
|
||||
stopped at the same time.
|
||||
|
||||
OpenVPN GUI is not able to retrieve any status info about the connections
|
||||
from OpenVPN, so it will report connected as soon as the service is
|
||||
started regarless of if OpenVPN has really succeded to connect or not.
|
||||
|
||||
You cannot see the OpenVPN log in real-time.
|
||||
|
||||
|
||||
Run Connect/Disconnect/Preconnect Scripts
|
||||
-----------------------------------------
|
||||
|
||||
There are three diffrent scripts that OpenVPN GUI can execute to help
|
||||
with diffrent tasks like mapping network drives.
|
||||
|
||||
Preconnect If a file named "xxx_pre.bat" exist in the config folder
|
||||
where xxx is the same as your OpenVPN config file name,
|
||||
this will be executed BEFORE the OpenVPN tunnel is established.
|
||||
|
||||
Connect If a file named "xxx_up.bat" exist in the config folder
|
||||
where xxx is the same as your OpenVPN config file name,
|
||||
this will be executed AFTER the OpenVPN tunnel is established.
|
||||
|
||||
Disconnect If a file named "xxx_down.bat" exist in the config folder
|
||||
where xxx is the same as your OpenVPN config file name,
|
||||
this will be executed BEFORE the OpenVPN tunnel is closed.
|
||||
|
||||
|
||||
Registry Values affecting the OpenVPN GUI operation
|
||||
---------------------------------------------------
|
||||
|
||||
All OpenVPN GUI reg-values are located below the following key:
|
||||
HKEY_LOCAL_MACHINE\SOFTWARE\OpenVPN-GUI\
|
||||
|
||||
The follow keys are used to control the OpenVPN GUI
|
||||
|
||||
config_dir
|
||||
configuration file directory, defaults to "C:\Program Files\OpenVPN\config"
|
||||
|
||||
config_ext
|
||||
file extension on configuration files, defaults to "ovpn"
|
||||
|
||||
connectscript_timeout
|
||||
Time in seconds to wait for the connect script to finish. If set to 0
|
||||
the exitcode of the script is not checked.
|
||||
|
||||
disconnectscript_timeout
|
||||
Time in seconds to wait for the disconnect script to finish. Must be a
|
||||
value between 1-99.
|
||||
|
||||
preconnectscript_timeout
|
||||
Time in seconds to wait for the preconnect script to finish. Must be a
|
||||
value between 1-99.
|
||||
|
||||
exe_path
|
||||
path to openvpn.exe, defaults to "C:\Program Files\OpenVPN\bin\openvpn.exe"
|
||||
|
||||
log_dir
|
||||
log file directory, defaults to "C:\Program Files\OpenVPN\log"
|
||||
|
||||
log_append
|
||||
if set to "0", the log file will be truncated every time you start a
|
||||
connection. If set to "1", the log will be appended to the log file.
|
||||
|
||||
priority
|
||||
the windows priority class for each instantiated OpenVPN process,
|
||||
can be one of:
|
||||
|
||||
* "IDLE_PRIORITY_CLASS"
|
||||
* "BELOW_NORMAL_PRIORITY_CLASS"
|
||||
* "NORMAL_PRIORITY_CLASS" (default)
|
||||
* "ABOVE_NORMAL_PRIORITY_CLASS"
|
||||
* "HIGH_PRIORITY_CLASS"
|
||||
|
||||
allow_edit
|
||||
If set to "1", the Edit config menu will be showed.
|
||||
|
||||
allow_password
|
||||
If set to "1", the Change Password menu will be showed.
|
||||
|
||||
allow_proxy
|
||||
If set to "1", the Proxy Settings menu will be showed.
|
||||
|
||||
allow_service
|
||||
If set to "1", the Service control menu will be showed.
|
||||
|
||||
silent_connection
|
||||
If set to "1", the status window with the OpenVPN log output will
|
||||
not be showed while connecting.
|
||||
|
||||
service_only
|
||||
If set to "1", OpenVPN GUI's normal "Connect" and "Disconnect"
|
||||
actions are changed so they start/stop the OpenVPN service instead
|
||||
of launching openvpn.exe directly.
|
||||
|
||||
show_balloon
|
||||
If set to "0" - Never show any connected balloon.
|
||||
"1" - Show balloon after initial connection is established.
|
||||
"2" - Show balloon even after re-connects.
|
||||
log_viewer
|
||||
The program used to view your log files, defaults to
|
||||
"C:\windows\notepad.exe"
|
||||
|
||||
editor
|
||||
The program used to edit your config files, defaults to
|
||||
"C:\windows\notepad.exe"
|
||||
|
||||
passphrase_attempts
|
||||
Number of attempts to enter the passphrase to allow.
|
||||
|
||||
All these registry options is also available as cmd-line options.
|
||||
Use "openvpn-gui --help" for more info about cmd-line options.
|
||||
|
||||
|
||||
If you have any problem getting OpenVPN GUI to work you can reach me via
|
||||
email at mathias@nilings.se.
|
||||
|
||||
|
||||
Building OpenVPN GUI from source
|
||||
--------------------------------
|
||||
|
||||
* Download and install MinGW and MSYS from http://www.mingw.org/
|
||||
I'm using MinGW-3.2.0-rc-3 and MSYS-1.0.10.
|
||||
|
||||
* Download and install the binary distribution of OpenSSL from
|
||||
http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
|
||||
* Download and extract the OpenVPN GUI source archive.
|
||||
|
||||
* Start a bash shell by running msys.bat.
|
||||
|
||||
* Run "make" from the OpenVPN GUI source directory.
|
|
@ -0,0 +1,635 @@
|
|||
[1.0.3 2005-08-18]
|
||||
|
||||
Bug Fixes:
|
||||
There was a bug in the code that expands variables in
|
||||
registry values. If the expanded string was longer than
|
||||
the original string it got incorrectly truncated.
|
||||
|
||||
|
||||
[1.0.2 2005-07-27]
|
||||
|
||||
Pass paths read in OpenVPN GUI's registry values through
|
||||
ExpandEnvironmentStrings(). This allows the use of Windows
|
||||
variables like %HOMEPATH% or %PROGRAMFILES%. This allows
|
||||
multiple users on the same system to have their own set
|
||||
of config files and keys in their home dir.
|
||||
|
||||
|
||||
[1.0.1 2005-06-10]
|
||||
|
||||
Bug Fixes:
|
||||
The Change Password feature did not work correctly when TABs
|
||||
were used in the config file between the key/pkcs12 keyword and
|
||||
the accual path to the key file.
|
||||
|
||||
|
||||
[1.0 2005-04-21]
|
||||
|
||||
No changes
|
||||
|
||||
|
||||
[1.0-rc5 2005-03-29]
|
||||
|
||||
Bug Fixes:
|
||||
[Pre/Dis]Connect scripts were not executed when starting or stopping
|
||||
the OpenVPN Service, or using "Service Only" mode.
|
||||
|
||||
|
||||
[1.0-rc4 2005-02-17]
|
||||
|
||||
Increased the width of buttons and space between text labels and edit
|
||||
controls on dialogs to ease localization of OpenVPN GUI.
|
||||
|
||||
Bug Fixes:
|
||||
Some fixed text strings was introduced in the code in 1.0-rc3. These
|
||||
are moved to the resource file now to allow localization.
|
||||
|
||||
If starting the OpenVPN service failed, OpenVPN GUI would get
|
||||
stuck with a yellow icon.
|
||||
|
||||
|
||||
[1.0-rc3 2005-02-14]
|
||||
|
||||
New Features:
|
||||
New registry value (show_balloon) to control whether to show the
|
||||
"Connected Balloon" or not. show_ballon can have the following values
|
||||
|
||||
0=Never show any balloon.
|
||||
1=Show balloon when the connection establishes (default).
|
||||
2=Show balloon every time OpenVPN has reconnected (old behavior).
|
||||
|
||||
Show "Connected since: XXX" and "Assigned IP: X.X.X.X" in the tray
|
||||
icon tip msg.
|
||||
|
||||
If a batch file named xxx_pre.bat exists in the config folder, where
|
||||
xxx is the same name as an OpenVPN config file, this will be executed
|
||||
before OpenVPN is launced.
|
||||
|
||||
If a batch file named xxx_down.bat exists in the config folder, where
|
||||
xxx is the same name as an OpenVPN config file, this will be executed
|
||||
on disconnect, but before the OpenVPN tunnel is closed.
|
||||
|
||||
Registry value "show_script_window" controls whether _up, _down and
|
||||
_pre scripts should execute in the background or in a visible cmd-line
|
||||
window.
|
||||
|
||||
Registry value "[pre/dis]connectscript_timeout" controls how long to
|
||||
wait for each script to finish.
|
||||
|
||||
Updated information on the about dialog.
|
||||
|
||||
Bug Fixes:
|
||||
Removed unused code that tried to determine the path to "Program
|
||||
Files". This code caused an error in some rare occasions.
|
||||
|
||||
|
||||
[1.0-rc2 2005-01-12]
|
||||
|
||||
New Features:
|
||||
Support for one level of subdirectories below the config directory.
|
||||
This means that if you have multiple connections, you can now put
|
||||
them in a seperate subdirectory together with their keys and certs.
|
||||
|
||||
"Service Only" mode. This is a mode that makes OpenVPN GUI more
|
||||
friendly to use for non-admin users to control the OpenVPN Service.
|
||||
Enable this mode by setting the registry value "service_only" to "1".
|
||||
|
||||
In this mode the following happends:
|
||||
|
||||
* The normal "Connect", "Disconnect" and "Show Status" is removed.
|
||||
|
||||
* The Service menu items "Start", "Stop" and "Restart" is replaced
|
||||
by "Connect", "Disconnect" and "Reconnect" directly on the main
|
||||
menu. These now control the OpenVPN Service instead.
|
||||
|
||||
* Dubbleclicking the icon starts the OpenVPN Service.
|
||||
|
||||
* Dubbleclicking the icon when the service is running brings up a
|
||||
dialog asking if you want to disconnect.
|
||||
|
||||
* The Proxy Settings menu item is removed as it can't control the service anyway.
|
||||
|
||||
The "OpenVPN Service started" dialog msg is replaced with a
|
||||
balloon msg.
|
||||
|
||||
Ask the user if he really wants to exit OpenVPN GUI if the OpenVPN
|
||||
Service is running.
|
||||
|
||||
Bug Fixes:
|
||||
Full rights were required to control the OpenVPN Service. Now only
|
||||
Start/Stop permissions are required, which allows a normal user to
|
||||
control the OpenVPN Service if these rights are granted to the user.
|
||||
(Can be done with subinacl.exe from the resource kit)
|
||||
|
||||
When passwords were retrieved from a user, OpenVPN GUI received them
|
||||
in the default windows codepage (ISO 8859-1 on english XP), and this
|
||||
was passed on untouched to OpenVPN. When OpenVPN is run from command-
|
||||
line on the other hand, the old DOS CP850 codepage is used. This
|
||||
caused passwords containing non-ASCII (7-bit) chars that worked from
|
||||
cmd-line not to work from OpenVPN GUI. This is now solved by
|
||||
retrieving passwords in unicode and translate them to CP850 before
|
||||
supplying them to OpenVPN.
|
||||
|
||||
Re-scan the config dir for new files when dubble-clicking the tray
|
||||
icon.
|
||||
|
||||
|
||||
[1.0-rc1 2005-01-06]
|
||||
|
||||
New Features:
|
||||
Show a warning message if "log" or "log-append" is found in the config
|
||||
file.
|
||||
|
||||
Bug Fixed:
|
||||
Added a bunch of compiler warnings which revealed a lot of minor
|
||||
programming errors. Mostly cast conversion errors between signed and
|
||||
unsigned intergers. All fixed now.
|
||||
|
||||
Set focus on the log window when the status window is re-opened to make
|
||||
sure the log is scrolled automatically.
|
||||
|
||||
Set focus on the log window when clicking disconnect to allow the log
|
||||
to continue scrolling automatically until OpenVPN is terminated.
|
||||
|
||||
|
||||
[1.0-beta26 2004-12-04]
|
||||
|
||||
New Features:
|
||||
Show "Connecting to: xxx" msg in tray icon tip message in addition to
|
||||
the previously displayed "Connected to:" msg.
|
||||
|
||||
Bug Fixes:
|
||||
Don't ask if you are sure you want to change your password to an EMPTY
|
||||
password if you're not allowed to use passwords shorter than 8 chars.
|
||||
|
||||
Clear password buffers after use to avoid having passwords in memory.
|
||||
|
||||
|
||||
[1.0-beta25 2004-12-01]
|
||||
|
||||
Changed button labels on the status dialog from DisConnect and ReConnect
|
||||
to Disconnect and Reconnect.
|
||||
|
||||
Don't show "Assigned IP:" at all in the connected balloon if no IP
|
||||
address is known, as when a real remote DHCP server is used.
|
||||
|
||||
Stripped out the last hardcoded strings to the resource file.
|
||||
|
||||
Raised maximum number of configs from 20 to 50.
|
||||
|
||||
Bug Fixes:
|
||||
If OpenVPN printed a line longer that 1024 chars, OpenVPN GUI would crash.
|
||||
This could happend when using "verb 5" or higher as OpenVPN then prints
|
||||
an "r" or "w" for every packet without any line breaks. A new line will
|
||||
now be inserted when 1024 chars is reached.
|
||||
|
||||
Ask if you want to close active connections when WM_CLOSE is received.
|
||||
|
||||
Handle WM_QUERYENDSESSION and WM_ENDSESSION correctly by closing any
|
||||
active connections and then terminate.
|
||||
|
||||
|
||||
[1.0-beta24 2004-11-15]
|
||||
|
||||
Bug Fixes:
|
||||
Some openssl #includes were not #ifdef:ed when building a nochangepsw
|
||||
version causing the build to fail if the openssl headers were not
|
||||
available.
|
||||
|
||||
When using OpenVPN 1.5/1.6 and entering a false private key passphrase,
|
||||
OpenVPN GUI would falsely think that the user attempted to start another
|
||||
connection.
|
||||
|
||||
|
||||
[1.0-beta23 2004-11-08]
|
||||
|
||||
Bug Fixes:
|
||||
Passphrase protected keys stored in MS Certificate Store did not work
|
||||
due to the way the openvpn console window was hidden.
|
||||
|
||||
|
||||
[1.0-beta22 2004-11-05]
|
||||
|
||||
Bug Fixes:
|
||||
OpenVPN GUI did not pass a CR/LF correctly after supplying OpenVPN
|
||||
with the private key passphrase! OpenVPN 2.0-beta12 and higher which
|
||||
uses a new prompt worked, but not earlier versions of OpenVPN.
|
||||
|
||||
If the Shell (explorer.exe) is restarted, OpenVPN GUI did not
|
||||
re-register the tray icon.
|
||||
|
||||
|
||||
[1.0-beta21 2004-10-29]
|
||||
|
||||
New Features:
|
||||
Added support for username/password based authentication.
|
||||
|
||||
Support for Localization. Language have to chosen at build time.
|
||||
Available are english, german, czech and swedish.
|
||||
|
||||
Bug Fixes:
|
||||
Fixed crash after displaying that too many connections exist.
|
||||
|
||||
Removed duplicate length-check on setting new password.
|
||||
|
||||
Fixed error dialog which had the error message shown in window caption.
|
||||
|
||||
Status windows did not change to yellow icon while ReConnecting.
|
||||
|
||||
DisConnect and ReConnect button was not disabled after a termination.
|
||||
This bug was introduced with beta20.
|
||||
|
||||
The Change Password feature did not parse the key/pkcs12 line in the
|
||||
config file correctly if there was TABs after the filename.
|
||||
|
||||
The Change Password feature did not work if a relative path with
|
||||
subdirectories was used.
|
||||
|
||||
|
||||
[1.0-beta20 2004-10-18]
|
||||
|
||||
New Features:
|
||||
Accept the new passphrase prompt introduced with OpenVPN 2.0-beta12.
|
||||
|
||||
When the machine is about to enter suspend mode the connection is
|
||||
closed. When the machine is powered up again, the connection is
|
||||
re-established.
|
||||
|
||||
Registry option "disconnect_on_suspend". Set to zero to disable the
|
||||
above feature.
|
||||
|
||||
ReConnect button on the status dialog.
|
||||
|
||||
Registry option "allow_proxy" to hide the Proxy Settings menu item.
|
||||
|
||||
Registry option "silent_connection" that suppresses the status
|
||||
dialog from being showed while connecting.
|
||||
|
||||
Command-line option to set the time to wait for the connect script
|
||||
to finish.
|
||||
|
||||
Icon color now reflects the status of the OpenVPN Service.
|
||||
|
||||
Bug Fixes:
|
||||
Included shellapi.h with the sourcecode, as the one distributed with
|
||||
the current stable version of MinGW miss some definitions.
|
||||
|
||||
When closing OpenVPN GUI it waits for all connections to close before
|
||||
exiting (Max 5 sec).
|
||||
|
||||
Made the password dialog always be on top of other windows.
|
||||
|
||||
Fixed a bug that occured if opening the log file for writing failed.
|
||||
(which happends if you try to run OpenVPN GUI without admin rights)
|
||||
|
||||
The menuitems on the OpenVPN Service menu was incorrectly enabled/
|
||||
disabled. This bug was introduced with beta19 as a result of the
|
||||
dynamic rescanning for configs on every menu opening.
|
||||
|
||||
Starting OpenVPN GUI with OpenVPN 1.5/1.6 installed and OpenVPN
|
||||
Service running failed with previous versions. (CreateEvent() error)
|
||||
|
||||
The installation package did not remove the OpenVPN-GUI registry key
|
||||
on uninstall.
|
||||
|
||||
Removed dependency on libeay32.dll for the no change password build.
|
||||
|
||||
|
||||
[1.0-beta19 2004-09-22]
|
||||
|
||||
New Features:
|
||||
The menu is restructured. Previous versions had all "actions" on the
|
||||
main menu, and a submenu with all configs for every action. This version
|
||||
lists all configs on the main menu, and have a submenu with actions.
|
||||
|
||||
If only one config exist, the actions are placed on the main menu.
|
||||
|
||||
If no connection is running, the config dir is re-scanned for configs
|
||||
every time the menu is opened.
|
||||
|
||||
If a file exists in the config folder named xxxx_up.bat, where xxxx
|
||||
is the same name as an existing config file, this batch file will be
|
||||
executed after a connection has been establish. If the batch file
|
||||
fails (return an exitcode other than 0), an error message is displayed.
|
||||
|
||||
Auto-hide status window after a connection is established and show
|
||||
a systray info balloon instead.
|
||||
|
||||
Show assigned IP address in connected balloon.
|
||||
|
||||
Don't allow starting multiple instances of OpenVPN GUI.
|
||||
|
||||
Added a cancel button to the Ask Password dialog.
|
||||
|
||||
Bug Fixes:
|
||||
Removed [nopass] parameter on --connect option as the password prompt
|
||||
is only showed if the private key really is passphrase protected.
|
||||
|
||||
Show an error msg if --connect refers to a non existing config file.
|
||||
|
||||
Ignore case of config file extension.
|
||||
|
||||
|
||||
[1.0-beta18 2004-09-13]
|
||||
|
||||
New Features:
|
||||
New Icons! Supplied by Radek Hladik.
|
||||
|
||||
If only one config file exists, dubble-clicking the systray icon will
|
||||
start that connection.
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
A bug in the GetRegKey() function caused OpenVPN GUI sometimes to
|
||||
fail starting with the following error msg:
|
||||
Error creating exit_event when checking openvpn version.
|
||||
|
||||
|
||||
[1.0-beta17 2004-09-02]
|
||||
|
||||
New Features:
|
||||
A dialog to configure Proxy Settings. You can now set http-proxy or
|
||||
socks-proxy address and port from the GUI. You can also make the GUI
|
||||
ask for proxy username and password, which will then be supplied to
|
||||
OpenVPN via an auth file.
|
||||
|
||||
Use Internet Explorer Proxy Settings (Ewan Bhamrah Harley)
|
||||
|
||||
A "Hide" button on the status dialog.
|
||||
|
||||
Show an error message if the client certificate has expired or is not
|
||||
yet valid.
|
||||
|
||||
Bug Fixes:
|
||||
If OpenVPN was installed in a non default folder, OpenVPN GUI would try
|
||||
to locate openvpn.exe, log-dir and conf-dir in the default openvpn
|
||||
folder anyway. Fixed in this version.
|
||||
|
||||
OpenVPN GUI tried to check the status of the OpenVPN Service even
|
||||
if the service menu was disabled in the registry, which caused an
|
||||
error message to be showed if the service was not installed properly.
|
||||
|
||||
Wait for two seconds when exiting OpenVPN GUI, so running openvpn
|
||||
processes can exit cleanly.
|
||||
|
||||
Disable Disconnect menu item while waiting for an openvpn process
|
||||
to terminate.
|
||||
|
||||
|
||||
[1.0-beta16 2004-08-25]
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
When only a filename (no full path) was specified in the config file
|
||||
for --key or --pkcs12, OpenVPN GUI did not look for the file in the
|
||||
config dir when changing password. Fixed in this version.
|
||||
|
||||
|
||||
[1.0-beta15 2004-08-25]
|
||||
|
||||
When changing password, require new password to be at least 8 chars.
|
||||
|
||||
|
||||
[v1.0-beta14 2004-08-24]
|
||||
|
||||
New Features:
|
||||
Change password of the private key. Both PEM and PKCS #12 files
|
||||
are supported.
|
||||
|
||||
|
||||
[v1.0-beta13 2004-08-19]
|
||||
|
||||
New Features:
|
||||
Shows which connections are connected in the TrayIcon tip msg
|
||||
|
||||
Bug Fixes:
|
||||
The "Enter Passphrase" dialog was a bit miss-designed. The textlabel
|
||||
and the editbox was overlapping a few pixels which made it look a
|
||||
little strange in some occasions.
|
||||
|
||||
|
||||
[v1.0-beta12 2004-08-16]
|
||||
|
||||
New Features:
|
||||
Show a Status Window while connecting that shows the output from
|
||||
OpenVPN in real-time.
|
||||
|
||||
A new menuitem to show the real-time status window.
|
||||
|
||||
If only one connection is running, dubbleclicking the trayicon will
|
||||
show the status window for the running connection.
|
||||
|
||||
Show a yellow TrayIcon while connecting.
|
||||
|
||||
Detect "restarting process" message, and shows "Connecting" status
|
||||
until a new connected msg is received.
|
||||
|
||||
|
||||
[v1.0-beta11a 2004-08-15]
|
||||
|
||||
Bug Fix:
|
||||
The exit_event handle was not closed after checking the openvpn version
|
||||
which made it impossible to restart connections with OpenVPN versions
|
||||
lower than 2.0-beta6. You received the following msg when trying to
|
||||
connect a second time:
|
||||
|
||||
"I seem to be running as a service, but my exit event object is telling
|
||||
me to exit immediately"
|
||||
|
||||
This bug was introduced with OpenVPN GUI v1.0-beta10.
|
||||
|
||||
|
||||
[v1.0-beta11 2004-08-09]
|
||||
|
||||
New Features:
|
||||
This version is bundled with a patched version of openvpn that will
|
||||
output a log message AFTER routes have been added to the system. This
|
||||
allows the GUI to report "Connected" after this msg. This patch will
|
||||
be included in next official release of OpenVPN 2.0-beta, so the GUI
|
||||
will continue to work with future official releases of openvpn. Older
|
||||
versions of openvpn will still work with this version of OpenVPN GUI,
|
||||
but "Connected" will then be reported before routes are added as it
|
||||
did with OpenVPN GUI 1.0-beta10.
|
||||
|
||||
If wrong passphrase is entered, openvpn will automatically be restarted
|
||||
a specified nr of times (default 3), which allows the user to re-enter
|
||||
his passphrase.
|
||||
|
||||
Number of passphase attempts to allow can be specified with reg-key
|
||||
"passphrase_attempts" or cmd-line option with the same name.
|
||||
|
||||
Bug Fixes:
|
||||
An empty line was printed in the log when prompting for passphrase.
|
||||
|
||||
|
||||
[v1.0-beta10 2004-08-08]
|
||||
|
||||
Default registry setting for showing the "Edit Config" menuitem is
|
||||
changed to "1" (Show it). If a previous version of OpenVPN GUI has
|
||||
been used, the registry key will of cource not change without manually
|
||||
changing it.
|
||||
|
||||
New Features:
|
||||
Check version of openvpn.exe, so it can support all versions of OpenVPN
|
||||
without a special build of OpenVPN GUI. Tested with 1.5.0, 1.6.0,
|
||||
2.0-beta4, 2.0-beta7 and 2.0-beta10. Older versions than 2.0-beta6 still
|
||||
only support one simultaneous connection though.
|
||||
|
||||
Redirect StdIn/StdOut/StdErr through OpenVPN GUI, so we can pass the
|
||||
private key passphrase to openvpn without requiring a patched version
|
||||
of OpenVPN. This also allows OpenVPN GUI to prompt for a passphrase only
|
||||
when it's needed.
|
||||
|
||||
If connecting fails, ask the user if he wants to view the log.
|
||||
|
||||
Show a dialog while connecting to allow the user to abort the connection.
|
||||
|
||||
Bug Fixes:
|
||||
Disable both "Connect" and "DisConnect" while connecting.
|
||||
|
||||
|
||||
[v1.0-beta9 2004-07-23]
|
||||
|
||||
The passphrase support added in v1.5-beta1 has been merched into the v1.0
|
||||
source so v1.5 does not exist any longer!
|
||||
|
||||
New Features:
|
||||
Cmd-line options:
|
||||
--connect cnn [nopass]: Autoconnect to "cnn" at startup. If "nopass"
|
||||
is used, no passphrase will be asked for.
|
||||
--help : Show list of cmd-line options.
|
||||
|
||||
And all registry settings is now available as cmd-line options:
|
||||
--exe_path : Path to openvpn.exe.\n"
|
||||
--config_dir : Path to dir to search for config files in.\n"
|
||||
--ext_string : Extension on config files.\n"
|
||||
--log_dir : Path to dir where log files will be saved.\n"
|
||||
--priority_string : Priority string (See install.txt for more info).\n"
|
||||
--append_string : 1=Append to log file. 0=Truncate logfile.\n"
|
||||
--log_viewer : Path to log viewer.\n"
|
||||
--editor : Path to config editor.\n"
|
||||
--allow_edit : 1=Show Edit Config menu\n"
|
||||
--allow_service : 1=Show Service control menu\n"
|
||||
|
||||
Bug Fixes:
|
||||
If the GUI was started from a cmd prompt and no passphrase was given
|
||||
openvpn.exe would query the user for the passphrase from the console
|
||||
(which is not showed), so the openvpn process got stuck there.
|
||||
|
||||
|
||||
[v1.5-beta1 2004-07-16]
|
||||
|
||||
This version is based on v1.0-beta8.
|
||||
|
||||
v1.5 is just a temporary version in wait for the management interface
|
||||
to OpenVPN. When this is available features added in v1.5 will be
|
||||
rewritten to use this interface instead in v2.0 of OpenVPN-GUI.
|
||||
|
||||
New Features:
|
||||
Support for passphrase protected private keys. OpenVPN-GUI will now
|
||||
always query the user for a passphrase before connecting. The
|
||||
passphrase is then supplied to OpenVPN via the --passphrase option.
|
||||
This requires a patched version of OpenVPN that supports the
|
||||
--passphrase option. A patched version that supports this is included
|
||||
in the OpenVPN-GUI v1.5-betaX installation package.
|
||||
|
||||
The user will always be asked for a passphrase even if the private
|
||||
key is not encrypted. This is because the GUI does not know in advance
|
||||
if the key is encrypted or not. This will be fixed in v2.0 when we
|
||||
have the management interface ready.
|
||||
|
||||
|
||||
[v1.0-beta8 2004-07-16]
|
||||
New Features:
|
||||
Tray Icon now shows red/green if any connection is established.
|
||||
|
||||
Bug Fixes:
|
||||
If something failed before starting openvpn.exe, exit_event and
|
||||
log_handle was not closed correctly which could make it impossible
|
||||
to make any more connections without restarting OpenVPN-GUI.
|
||||
|
||||
|
||||
[v1.0-beta7 2004-07-08]
|
||||
New Features:
|
||||
A seperate build version supporting OpenVPN v1.5, v1.6 and the
|
||||
2.0 series before beta6. This version only supports having one
|
||||
connection running at the same time.
|
||||
|
||||
Added an About box.
|
||||
|
||||
If there are active connections when "Exit OpenVPN-GUI" is selected,
|
||||
a "Are you sure you want to exit?" box is displayed.
|
||||
|
||||
Bug Fixes
|
||||
It was not possible to have cmd-line options on the reg-keys
|
||||
"log_viewer" or "editor". This is now possible.
|
||||
|
||||
|
||||
[v1.0-beta6 2004-07-05]
|
||||
Bug Fixes:
|
||||
The default values for paths created by beta3, beta4 and beta5 used
|
||||
hardcoded values for "C:\windows..." and "C:\program files...", which
|
||||
did not work on some localized Windows versions that is not using
|
||||
these folders. This is fixed now by getting those pathnames from the
|
||||
system.
|
||||
|
||||
*** If you have installed beta3-beta5 you need to manualy delete the
|
||||
whole HKEY_LM\SOFTWARE\OpenVPN-GUI key in the registry. The correct
|
||||
reg-keys will then be recreated when OpenVPN-GUI is started. ***
|
||||
|
||||
|
||||
[v1.0-beta5 2004-07-04]
|
||||
New Features:
|
||||
Menu-commands to Start/Stop/Restart the OpenVPN Service. Enable this
|
||||
feature by setting the following reg-key to 1:
|
||||
HKEY_LM\SOFTWARE\OpenVPN-GUI\allow_service
|
||||
|
||||
Bug Fixes:
|
||||
v1.0-beta4 always opened the registry with write-access, which made
|
||||
it imposible to start it without administator rights.
|
||||
|
||||
|
||||
[v1.0-beta4 2004-07-04]
|
||||
New Features:
|
||||
Menu-command to open a config-file for editing. Enable this feature
|
||||
by setting the following reg-key to 1:
|
||||
HKEY_LM\SOFTWARE\OpenVPN-GUI\allow_edit
|
||||
|
||||
|
||||
[v1.0-beta3 2004-07-04]
|
||||
New Features:
|
||||
Log Viewer. As default OpenVPN-GUI launches Notepad to view the log.
|
||||
The program used to view the log can be changed with this reg-key:
|
||||
HKEY_LM\SOFTWARE\OpenVPN-GUI\log-viewer
|
||||
|
||||
OpenVPN-GUI now uses its own registry-keys, instead of the same as
|
||||
the service wrapper uses. It now stores its values under this key:
|
||||
HKEY_LM\SOFTWARE\OpenVPN-GUI\
|
||||
If this key does not exist, OpenVPN-GUI will create it with the same
|
||||
default values as the service-wrapper uses, so if you want to use the
|
||||
service-wrapper on config-files indepentent of the GUI you should
|
||||
change the "config-dir" key to another folder.
|
||||
|
||||
|
||||
[v1.0-beta2 2004-07-03]
|
||||
New Features:
|
||||
Connect/Disconnect now shows a sub-menu so each connection can be
|
||||
brought up/down individually.
|
||||
|
||||
Upon connect OpenVPN-GUI will wait for 3 seconds and then check if
|
||||
the openvpn process is still alive and report "Connection successful"
|
||||
only if this is the case.
|
||||
|
||||
OpenVPN-GUI monitors the openvpn processes it has started, and if a
|
||||
process is terminated before the user has chosen to take it down, this
|
||||
will be reported to the user.
|
||||
|
||||
If no config files is found when OpenVPN-GUI is started, it will
|
||||
notify the user of this and terminate.
|
||||
|
||||
|
||||
[v1.0-beta1 2004-07-02] Initial release
|
||||
Features:
|
||||
Adds itself as a system tray icon.
|
||||
Menuitem "Connect" - Starts openvpn for all config-files it has found.
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
WCHAR unicode_to_ascii[256] = {
|
||||
0x0000,
|
||||
0x0001,
|
||||
0x0002,
|
||||
0x0003,
|
||||
0x0004,
|
||||
0x0005,
|
||||
0x0006,
|
||||
0x0007,
|
||||
0x0008,
|
||||
0x0009,
|
||||
0x000a,
|
||||
0x000b,
|
||||
0x000c,
|
||||
0x000d,
|
||||
0x000e,
|
||||
0x000f,
|
||||
0x0010,
|
||||
0x0011,
|
||||
0x0012,
|
||||
0x0013,
|
||||
0x0014,
|
||||
0x0015,
|
||||
0x0016,
|
||||
0x0017,
|
||||
0x0018,
|
||||
0x0019,
|
||||
0x001a,
|
||||
0x001b,
|
||||
0x001c,
|
||||
0x001d,
|
||||
0x001e,
|
||||
0x001f,
|
||||
0x0020,
|
||||
0x0021,
|
||||
0x0022,
|
||||
0x0023,
|
||||
0x0024,
|
||||
0x0025,
|
||||
0x0026,
|
||||
0x0027,
|
||||
0x0028,
|
||||
0x0029,
|
||||
0x002a,
|
||||
0x002b,
|
||||
0x002c,
|
||||
0x002d,
|
||||
0x002e,
|
||||
0x002f,
|
||||
0x0030,
|
||||
0x0031,
|
||||
0x0032,
|
||||
0x0033,
|
||||
0x0034,
|
||||
0x0035,
|
||||
0x0036,
|
||||
0x0037,
|
||||
0x0038,
|
||||
0x0039,
|
||||
0x003a,
|
||||
0x003b,
|
||||
0x003c,
|
||||
0x003d,
|
||||
0x003e,
|
||||
0x003f,
|
||||
0x0040,
|
||||
0x0041,
|
||||
0x0042,
|
||||
0x0043,
|
||||
0x0044,
|
||||
0x0045,
|
||||
0x0046,
|
||||
0x0047,
|
||||
0x0048,
|
||||
0x0049,
|
||||
0x004a,
|
||||
0x004b,
|
||||
0x004c,
|
||||
0x004d,
|
||||
0x004e,
|
||||
0x004f,
|
||||
0x0050,
|
||||
0x0051,
|
||||
0x0052,
|
||||
0x0053,
|
||||
0x0054,
|
||||
0x0055,
|
||||
0x0056,
|
||||
0x0057,
|
||||
0x0058,
|
||||
0x0059,
|
||||
0x005a,
|
||||
0x005b,
|
||||
0x005c,
|
||||
0x005d,
|
||||
0x005e,
|
||||
0x005f,
|
||||
0x0060,
|
||||
0x0061,
|
||||
0x0062,
|
||||
0x0063,
|
||||
0x0064,
|
||||
0x0065,
|
||||
0x0066,
|
||||
0x0067,
|
||||
0x0068,
|
||||
0x0069,
|
||||
0x006a,
|
||||
0x006b,
|
||||
0x006c,
|
||||
0x006d,
|
||||
0x006e,
|
||||
0x006f,
|
||||
0x0070,
|
||||
0x0071,
|
||||
0x0072,
|
||||
0x0073,
|
||||
0x0074,
|
||||
0x0075,
|
||||
0x0076,
|
||||
0x0077,
|
||||
0x0078,
|
||||
0x0079,
|
||||
0x007a,
|
||||
0x007b,
|
||||
0x007c,
|
||||
0x007d,
|
||||
0x007e,
|
||||
0x007f,
|
||||
0x00c7,
|
||||
0x00fc,
|
||||
0x00e9,
|
||||
0x00e2,
|
||||
0x00e4,
|
||||
0x00e0,
|
||||
0x00e5,
|
||||
0x00e7,
|
||||
0x00ea,
|
||||
0x00eb,
|
||||
0x00e8,
|
||||
0x00ef,
|
||||
0x00ee,
|
||||
0x00ec,
|
||||
0x00c4,
|
||||
0x00c5,
|
||||
0x00c9,
|
||||
0x00e6,
|
||||
0x00c6,
|
||||
0x00f4,
|
||||
0x00f6,
|
||||
0x00f2,
|
||||
0x00fb,
|
||||
0x00f9,
|
||||
0x00ff,
|
||||
0x00d6,
|
||||
0x00dc,
|
||||
0x00f8,
|
||||
0x00a3,
|
||||
0x00d8,
|
||||
0x00d7,
|
||||
0x0192,
|
||||
0x00e1,
|
||||
0x00ed,
|
||||
0x00f3,
|
||||
0x00fa,
|
||||
0x00f1,
|
||||
0x00d1,
|
||||
0x00aa,
|
||||
0x00ba,
|
||||
0x00bf,
|
||||
0x00ae,
|
||||
0x00ac,
|
||||
0x00bd,
|
||||
0x00bc,
|
||||
0x00a1,
|
||||
0x00ab,
|
||||
0x00bb,
|
||||
0x2591,
|
||||
0x2592,
|
||||
0x2593,
|
||||
0x2502,
|
||||
0x2524,
|
||||
0x00c1,
|
||||
0x00c2,
|
||||
0x00c0,
|
||||
0x00a9,
|
||||
0x2563,
|
||||
0x2551,
|
||||
0x2557,
|
||||
0x255d,
|
||||
0x00a2,
|
||||
0x00a5,
|
||||
0x2510,
|
||||
0x2514,
|
||||
0x2534,
|
||||
0x252c,
|
||||
0x251c,
|
||||
0x2500,
|
||||
0x253c,
|
||||
0x00e3,
|
||||
0x00c3,
|
||||
0x255a,
|
||||
0x2554,
|
||||
0x2569,
|
||||
0x2566,
|
||||
0x2560,
|
||||
0x2550,
|
||||
0x256c,
|
||||
0x00a4,
|
||||
0x00f0,
|
||||
0x00d0,
|
||||
0x00ca,
|
||||
0x00cb,
|
||||
0x00c8,
|
||||
0x0131,
|
||||
0x00cd,
|
||||
0x00ce,
|
||||
0x00cf,
|
||||
0x2518,
|
||||
0x250c,
|
||||
0x2588,
|
||||
0x2584,
|
||||
0x00a6,
|
||||
0x00cc,
|
||||
0x2580,
|
||||
0x00d3,
|
||||
0x00df,
|
||||
0x00d4,
|
||||
0x00d2,
|
||||
0x00f5,
|
||||
0x00d5,
|
||||
0x00b5,
|
||||
0x00fe,
|
||||
0x00de,
|
||||
0x00da,
|
||||
0x00db,
|
||||
0x00d9,
|
||||
0x00fd,
|
||||
0x00dd,
|
||||
0x00af,
|
||||
0x00b4,
|
||||
0x00ad,
|
||||
0x00b1,
|
||||
0x2017,
|
||||
0x00be,
|
||||
0x00b6,
|
||||
0x00a7,
|
||||
0x00f7,
|
||||
0x00b8,
|
||||
0x00b0,
|
||||
0x00a8,
|
||||
0x00b7,
|
||||
0x00b9,
|
||||
0x00b3,
|
||||
0x00b2,
|
||||
0x25a0,
|
||||
0x00a0
|
||||
};
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <WinInet.h>
|
||||
#include <malloc.h>
|
||||
|
||||
LPCTSTR getIeHttpProxyError=NULL;
|
||||
|
||||
/* getIeHttpProxy fetches the current IE proxy settings for http */
|
||||
|
||||
LPCTSTR getIeHttpProxy()
|
||||
{
|
||||
DWORD psize=0;
|
||||
INTERNET_PROXY_INFO *pinfo;
|
||||
LPTSTR proxyString;
|
||||
LPTSTR p;
|
||||
LPTSTR q;
|
||||
unsigned int len;
|
||||
|
||||
/* first see how big a buffer we need for the IPO structure */
|
||||
InternetQueryOption(NULL, INTERNET_OPTION_PROXY, NULL, &psize);
|
||||
if(!psize)
|
||||
{
|
||||
getIeHttpProxyError="InternetQueryOption failed to return buffer size";
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* allocate memory for IPO */
|
||||
pinfo = malloc (psize*sizeof(TCHAR));
|
||||
if (pinfo == NULL)
|
||||
{
|
||||
getIeHttpProxyError="malloc failed (1)";
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* now run the real query */
|
||||
if(!InternetQueryOption(NULL, INTERNET_OPTION_PROXY, (LPVOID) pinfo, &psize))
|
||||
{
|
||||
getIeHttpProxyError="InternetQueryOption() failed to find proxy info";
|
||||
free(pinfo);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/* see what sort of result we got */
|
||||
|
||||
if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_DIRECT)
|
||||
{
|
||||
/* No proxy configured */
|
||||
free(pinfo);
|
||||
return("");
|
||||
}
|
||||
else if(pinfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
|
||||
{
|
||||
/* we have a proxy - now parse result string */
|
||||
/* if result string does NOT contain an '=' sign then */
|
||||
/* there is a single proxy for all protocols */
|
||||
for (p=(LPTSTR)pinfo->lpszProxy; *p && *p != '='; p++);
|
||||
if(!*p)
|
||||
{
|
||||
/* single proxy */
|
||||
/* allocate a new string to return */
|
||||
len = 1+strlen(pinfo->lpszProxy);
|
||||
proxyString = malloc (len*sizeof(TCHAR));
|
||||
if (proxyString == NULL)
|
||||
{
|
||||
getIeHttpProxyError="malloc failed (2)";
|
||||
free(pinfo);
|
||||
return(NULL);
|
||||
}
|
||||
strncpy(proxyString, pinfo->lpszProxy,len);
|
||||
proxyString[len]=0;
|
||||
free(pinfo);
|
||||
return(proxyString);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* multiple space seperated proxies defined in the form */
|
||||
/* protocol=proxyhost[:port] */
|
||||
/* we want the one marked "http=", if any. */
|
||||
p=(LPTSTR)pinfo->lpszProxy;
|
||||
while(*p && strncmp(p, "http=", 5))
|
||||
{
|
||||
for(; *p && *p != ' '; p++);
|
||||
if(*p) p++;
|
||||
}
|
||||
if(*p)
|
||||
{
|
||||
/* found the proxy */
|
||||
p+=5;
|
||||
for(q=p; *q && *q != ' '; q++);
|
||||
/* allocate a buffer for the proxy information */
|
||||
len=1+(q-p);
|
||||
proxyString=malloc(len*sizeof(TCHAR));
|
||||
if(proxyString==NULL)
|
||||
{
|
||||
getIeHttpProxyError="malloc failed (3)";
|
||||
free(pinfo);
|
||||
return(NULL);
|
||||
}
|
||||
strncpy(proxyString, p, len);
|
||||
proxyString[len]=0;
|
||||
free(pinfo);
|
||||
return(proxyString);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No http proxy in list */
|
||||
free(pinfo);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* InternetQueryOption returned a proxy type we don't know about*/
|
||||
getIeHttpProxyError="Unknown Proxy Type";
|
||||
free(pinfo);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2004 Ewan Bhamrah Harley <code@ewan.info>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 __GETIEHTTPPROXY__
|
||||
#define __GETIEHTTPPROXY__
|
||||
extern LPTSTR getIeHttpProxyError;
|
||||
LPCTSTR getIeHttpProxy();
|
||||
#endif
|
|
@ -0,0 +1,500 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include <shlwapi.h>
|
||||
#include <Pbt.h>
|
||||
#include "tray.h"
|
||||
#include "openvpn.h"
|
||||
#include "openvpn_config.h"
|
||||
#include "viewlog.h"
|
||||
#include "service.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "passphrase.h"
|
||||
#include "proxy.h"
|
||||
#include "registry.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
/* Declare Windows procedure */
|
||||
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
|
||||
BOOL CALLBACK AboutDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void CloseApplication(HWND hwnd);
|
||||
|
||||
/* Class name and window title */
|
||||
char szClassName[ ] = "OpenVPN-GUI";
|
||||
char szTitleText[ ] = "OpenVPN";
|
||||
|
||||
/* Options structure */
|
||||
struct options o;
|
||||
|
||||
int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||
UNUSED HINSTANCE hPrevInstance,
|
||||
LPSTR lpszArgument,
|
||||
UNUSED int nCmdShow)
|
||||
{
|
||||
HWND hwnd; /* This is the handle for our window */
|
||||
MSG messages; /* Here messages to the application are saved */
|
||||
WNDCLASSEX wincl; /* Data structure for the windowclass */
|
||||
HWND hwndAbout;
|
||||
DWORD shell32_version;
|
||||
|
||||
|
||||
/* initialize options to default state */
|
||||
init_options (&o);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Open debug file for output */
|
||||
if (!(o.debug_fp = fopen(DEBUG_FILE, "w")))
|
||||
{
|
||||
/* can't open debug file */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_DEBUG_FILE, DEBUG_FILE);
|
||||
exit(1);
|
||||
}
|
||||
PrintDebug("Starting OpenVPN GUI v%s", GUI_VERSION);
|
||||
#endif
|
||||
|
||||
|
||||
o.hInstance = hThisInstance;
|
||||
|
||||
if(!GetModuleHandle("RICHED20.DLL"))
|
||||
{
|
||||
LoadLibrary("RICHED20.DLL");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* can't load riched20.dll */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_LOAD_RICHED20, "");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check version of shell32.dll */
|
||||
shell32_version=GetDllVersion("shell32.dll");
|
||||
if (shell32_version < PACKVERSION(5,0))
|
||||
{
|
||||
/* shell32.dll version to low */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_SHELL_DLL_VERSION, shell32_version);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PrintDebug("Shell32.dll version: 0x%lx", shell32_version);
|
||||
#endif
|
||||
|
||||
|
||||
/* Parse command-line options */
|
||||
Createargcargv(&o, lpszArgument);
|
||||
|
||||
/* Check if a previous instance is already running. */
|
||||
if ((FindWindow (szClassName, NULL)) != NULL)
|
||||
{
|
||||
/* GUI already running */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_GUI_ALREADY_RUNNING, "");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!GetRegistryKeys()) {
|
||||
exit(1);
|
||||
}
|
||||
if (!CheckVersion()) {
|
||||
exit(1);
|
||||
}
|
||||
if (!BuildFileList()) {
|
||||
exit(1);
|
||||
}
|
||||
if (!VerifyAutoConnections()) {
|
||||
exit(1);
|
||||
}
|
||||
GetProxyRegistrySettings();
|
||||
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
/* Initialize OpenSSL */
|
||||
OpenSSL_add_all_algorithms();
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
|
||||
/* The Window structure */
|
||||
wincl.hInstance = hThisInstance;
|
||||
wincl.lpszClassName = szClassName;
|
||||
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
|
||||
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
|
||||
wincl.cbSize = sizeof (WNDCLASSEX);
|
||||
|
||||
/* Use default icon and mouse-pointer */
|
||||
wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(APP_ICON));
|
||||
wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(APP_ICON));
|
||||
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
|
||||
wincl.lpszMenuName = NULL; /* No menu */
|
||||
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
|
||||
wincl.cbWndExtra = 0; /* structure or the window instance */
|
||||
/* Use Windows's default color as the background of the window */
|
||||
wincl.hbrBackground = (HBRUSH) COLOR_3DSHADOW; //COLOR_BACKGROUND;
|
||||
|
||||
/* Register the window class, and if it fails quit the program */
|
||||
if (!RegisterClassEx (&wincl))
|
||||
return 1;
|
||||
|
||||
/* The class is registered, let's create the program*/
|
||||
hwnd = CreateWindowEx (
|
||||
0, /* Extended possibilites for variation */
|
||||
szClassName, /* Classname */
|
||||
szTitleText, /* Title Text */
|
||||
WS_OVERLAPPEDWINDOW, /* default window */
|
||||
(int)CW_USEDEFAULT, /* Windows decides the position */
|
||||
(int)CW_USEDEFAULT, /* where the window ends up on the screen */
|
||||
230, /* The programs width */
|
||||
200, /* and height in pixels */
|
||||
HWND_DESKTOP, /* The window is a child-window to desktop */
|
||||
NULL, /* No menu */
|
||||
hThisInstance, /* Program Instance handler */
|
||||
NULL /* No Window Creation data */
|
||||
);
|
||||
|
||||
|
||||
/* Run the message loop. It will run until GetMessage() returns 0 */
|
||||
while (GetMessage (&messages, NULL, 0, 0))
|
||||
{
|
||||
TranslateMessage(&messages);
|
||||
DispatchMessage(&messages);
|
||||
}
|
||||
|
||||
/* The program return-value is 0 - The value that PostQuitMessage() gave */
|
||||
return messages.wParam;
|
||||
}
|
||||
|
||||
|
||||
/* This function is called by the Windows function DispatchMessage() */
|
||||
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static UINT s_uTaskbarRestart;
|
||||
int i;
|
||||
|
||||
switch (message) {
|
||||
case WM_CREATE:
|
||||
|
||||
/* Save Window Handle */
|
||||
o.hWnd = hwnd;
|
||||
|
||||
s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated"));
|
||||
|
||||
CreatePopupMenus(); /* Create popup menus */
|
||||
LoadAppIcon(); /* Load App Icon */
|
||||
ShowTrayIcon();
|
||||
if (o.allow_service[0]=='1' || o.service_only[0]=='1')
|
||||
CheckServiceStatus(); // Check if service is running or not
|
||||
if (!AutoStartConnections()) {
|
||||
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_NOTIFYICONTRAY:
|
||||
OnNotifyTray(lParam); // Manages message from tray
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
if ( (LOWORD(wParam) >= IDM_CONNECTMENU) && (LOWORD(wParam) < IDM_CONNECTMENU + MAX_CONFIGS) ) {
|
||||
StartOpenVPN(LOWORD(wParam) - IDM_CONNECTMENU);
|
||||
}
|
||||
if ( (LOWORD(wParam) >= IDM_DISCONNECTMENU) && (LOWORD(wParam) < IDM_DISCONNECTMENU + MAX_CONFIGS) ) {
|
||||
StopOpenVPN(LOWORD(wParam) - IDM_DISCONNECTMENU);
|
||||
}
|
||||
if ( (LOWORD(wParam) >= IDM_STATUSMENU) && (LOWORD(wParam) < IDM_STATUSMENU + MAX_CONFIGS) ) {
|
||||
ShowWindow(o.cnn[LOWORD(wParam) - IDM_STATUSMENU].hwndStatus, SW_SHOW);
|
||||
}
|
||||
if ( (LOWORD(wParam) >= IDM_VIEWLOGMENU) && (LOWORD(wParam) < IDM_VIEWLOGMENU + MAX_CONFIGS) ) {
|
||||
ViewLog(LOWORD(wParam) - IDM_VIEWLOGMENU);
|
||||
}
|
||||
if ( (LOWORD(wParam) >= IDM_EDITMENU) && (LOWORD(wParam) < IDM_EDITMENU + MAX_CONFIGS) ) {
|
||||
EditConfig(LOWORD(wParam) - IDM_EDITMENU);
|
||||
}
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
if ( (LOWORD(wParam) >= IDM_PASSPHRASEMENU) && (LOWORD(wParam) < IDM_PASSPHRASEMENU + MAX_CONFIGS) ) {
|
||||
ShowChangePassphraseDialog(LOWORD(wParam) - IDM_PASSPHRASEMENU);
|
||||
}
|
||||
#endif
|
||||
if (LOWORD(wParam) == IDM_PROXY) {
|
||||
ShowProxySettingsDialog();
|
||||
}
|
||||
if (LOWORD(wParam) == IDM_ABOUT) {
|
||||
DialogBox(o.hInstance, (LPCTSTR)IDD_ABOUTDIALOG, NULL, (DLGPROC)AboutDialogFunc);
|
||||
}
|
||||
if (LOWORD(wParam) == IDM_CLOSE) {
|
||||
CloseApplication(hwnd);
|
||||
}
|
||||
if (LOWORD(wParam) == IDM_SERVICE_START) {
|
||||
MyStartService();
|
||||
}
|
||||
if (LOWORD(wParam) == IDM_SERVICE_STOP) {
|
||||
MyStopService();
|
||||
}
|
||||
if (LOWORD(wParam) == IDM_SERVICE_RESTART) MyReStartService();
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
CloseApplication(hwnd);
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
StopAllOpenVPN();
|
||||
OnDestroyTray(); /* Remove Tray Icon and destroy menus */
|
||||
PostQuitMessage (0); /* Send a WM_QUIT to the message queue */
|
||||
break;
|
||||
|
||||
case WM_QUERYENDSESSION:
|
||||
return(TRUE);
|
||||
|
||||
case WM_ENDSESSION:
|
||||
StopAllOpenVPN();
|
||||
OnDestroyTray();
|
||||
break;
|
||||
|
||||
case WM_POWERBROADCAST:
|
||||
switch (wParam) {
|
||||
case PBT_APMSUSPEND:
|
||||
if (o.disconnect_on_suspend[0] == '1')
|
||||
{
|
||||
/* Suspend running connections */
|
||||
for (i=0; i<o.num_configs; i++)
|
||||
{
|
||||
if (o.cnn[i].connect_status == CONNECTED)
|
||||
SuspendOpenVPN(i);
|
||||
}
|
||||
|
||||
/* Wait for all connections to suspend */
|
||||
for (i=0; i<10; i++, Sleep(500))
|
||||
if (CountConnectedState(SUSPENDING) == 0) break;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case PBT_APMRESUMESUSPEND:
|
||||
case PBT_APMRESUMECRITICAL:
|
||||
for (i=0; i<o.num_configs; i++)
|
||||
{
|
||||
/* Restart suspend connections */
|
||||
if (o.cnn[i].connect_status == SUSPENDED)
|
||||
StartOpenVPN(i);
|
||||
|
||||
/* If some connection never reached SUSPENDED state */
|
||||
if (o.cnn[i].connect_status == SUSPENDING)
|
||||
StopOpenVPN(i);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
default: /* for messages that we don't deal with */
|
||||
if (message == s_uTaskbarRestart)
|
||||
{
|
||||
/* Explorer has restarted, re-register the tray icon. */
|
||||
ShowTrayIcon();
|
||||
CheckAndSetTrayIcon();
|
||||
break;
|
||||
}
|
||||
return DefWindowProc (hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL CALLBACK AboutDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
|
||||
{
|
||||
HICON hIcon;
|
||||
TCHAR buf[1000];
|
||||
char buf2[1000];
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
|
||||
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
if (hIcon) {
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
|
||||
}
|
||||
|
||||
/* Show version string */
|
||||
myLoadString(TEXT_ABOUT_OPENVPNGUI);
|
||||
mysnprintf(buf2, buf, GUI_VERSION);
|
||||
SetDlgItemText(hwndDlg, ID_TEXT_OPENVPNGUI, buf2);
|
||||
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK: // button
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CloseApplication(HWND hwnd)
|
||||
{
|
||||
int i, ask_exit=0;
|
||||
TCHAR buf[1000];
|
||||
|
||||
if (o.service_running == SERVICE_CONNECTED)
|
||||
{
|
||||
myLoadString(INFO_SERVICE_ACTIVE_EXIT);
|
||||
if (MessageBox(NULL, buf, "Exit OpenVPN", MB_YESNO) == IDNO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < o.num_configs; i++) {
|
||||
if (o.cnn[i].connect_status != 0) {
|
||||
ask_exit=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ask_exit) {
|
||||
/* aks for confirmation */
|
||||
myLoadString(INFO_ACTIVE_CONN_EXIT);
|
||||
if (MessageBox(NULL, buf, "Exit OpenVPN", MB_YESNO) == IDNO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void PrintDebugMsg(char *msg)
|
||||
{
|
||||
time_t log_time;
|
||||
struct tm *time_struct;
|
||||
char date[30];
|
||||
|
||||
log_time = time(NULL);
|
||||
time_struct = localtime(&log_time);
|
||||
snprintf(date, sizeof(date), "%d-%.2d-%.2d %.2d:%.2d:%.2d",
|
||||
time_struct->tm_year + 1900,
|
||||
time_struct->tm_mon + 1,
|
||||
time_struct->tm_mday,
|
||||
time_struct->tm_hour,
|
||||
time_struct->tm_min,
|
||||
time_struct->tm_sec);
|
||||
|
||||
fprintf(o.debug_fp, "%s %s\n", date, msg);
|
||||
fflush(o.debug_fp);
|
||||
}
|
||||
|
||||
void PrintErrorDebug(char *msg)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
char *buf;
|
||||
|
||||
/* Get last error message */
|
||||
if (!FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL ))
|
||||
{
|
||||
/* FormatMessage failed! */
|
||||
PrintDebug("FormatMessage() failed. %s ", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Cut of CR/LFs */
|
||||
buf = (char *)lpMsgBuf;
|
||||
buf[strlen(buf) - 3] = '\0';
|
||||
|
||||
PrintDebug("%s %s", msg, (LPCTSTR)lpMsgBuf);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
init_security_attributes_allow_all (struct security_attributes *obj)
|
||||
{
|
||||
CLEAR (*obj);
|
||||
|
||||
obj->sa.nLength = sizeof (SECURITY_ATTRIBUTES);
|
||||
obj->sa.lpSecurityDescriptor = &obj->sd;
|
||||
obj->sa.bInheritHandle = FALSE;
|
||||
if (!InitializeSecurityDescriptor (&obj->sd, SECURITY_DESCRIPTOR_REVISION))
|
||||
return false;
|
||||
if (!SetSecurityDescriptorDacl (&obj->sd, TRUE, NULL, FALSE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define PACKVERSION(major,minor) MAKELONG(minor,major)
|
||||
DWORD GetDllVersion(LPCTSTR lpszDllName)
|
||||
{
|
||||
HINSTANCE hinstDll;
|
||||
DWORD dwVersion = 0;
|
||||
|
||||
/* For security purposes, LoadLibrary should be provided with a
|
||||
fully-qualified path to the DLL. The lpszDllName variable should be
|
||||
tested to ensure that it is a fully qualified path before it is used. */
|
||||
hinstDll = LoadLibrary(lpszDllName);
|
||||
|
||||
if(hinstDll)
|
||||
{
|
||||
DLLGETVERSIONPROC pDllGetVersion;
|
||||
pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll,
|
||||
"DllGetVersion");
|
||||
|
||||
/* Because some DLLs might not implement this function, you
|
||||
must test for it explicitly. Depending on the particular
|
||||
DLL, the lack of a DllGetVersion function can be a useful
|
||||
indicator of the version. */
|
||||
|
||||
if(pDllGetVersion)
|
||||
{
|
||||
DLLVERSIONINFO dvi;
|
||||
HRESULT hr;
|
||||
|
||||
ZeroMemory(&dvi, sizeof(dvi));
|
||||
dvi.cbSize = sizeof(dvi);
|
||||
|
||||
hr = (*pDllGetVersion)(&dvi);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
|
||||
}
|
||||
}
|
||||
|
||||
FreeLibrary(hinstDll);
|
||||
}
|
||||
return dwVersion;
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <stdio.h>
|
||||
|
||||
/* Define this to enable DEBUG build */
|
||||
//#define DEBUG
|
||||
#define DEBUG_FILE "c:\\openvpngui_debug.txt"
|
||||
|
||||
/* Define this to disable Change Password support */
|
||||
//#define DISABLE_CHANGE_PASSWORD
|
||||
|
||||
#define GUI_NAME "OpenVPN GUI"
|
||||
#define GUI_VERSION "1.0.3"
|
||||
|
||||
/* Registry key for User Settings */
|
||||
#define GUI_REGKEY_HKCU "Software\\Nilings\\OpenVPN-GUI"
|
||||
|
||||
/* Registry key for Global Settings */
|
||||
#define GUI_REGKEY_HKLM "SOFTWARE\\OpenVPN-GUI"
|
||||
|
||||
#define MAX_LOG_LINES 500 /* Max number of lines in LogWindow */
|
||||
#define DEL_LOG_LINES 10 /* Number of lines to delete from LogWindow */
|
||||
|
||||
|
||||
|
||||
/* bool definitions */
|
||||
#define bool int
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
/* GCC function attributes */
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
#define NORETURN __attribute__ ((noreturn))
|
||||
|
||||
#define PACKVERSION(major,minor) MAKELONG(minor,major)
|
||||
struct security_attributes
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
};
|
||||
|
||||
|
||||
/* clear an object */
|
||||
#define CLEAR(x) memset(&(x), 0, sizeof(x))
|
||||
|
||||
/* snprintf with guaranteed null termination */
|
||||
#define mysnprintf(out, args...) \
|
||||
{ \
|
||||
snprintf (out, sizeof(out), args); \
|
||||
out [sizeof (out) - 1] = '\0'; \
|
||||
}
|
||||
|
||||
|
||||
/* Show Message */
|
||||
#define ShowMsg(caption, args...) \
|
||||
{ \
|
||||
char x_msg[256]; \
|
||||
mysnprintf (x_msg, args); \
|
||||
MessageBox(NULL, x_msg, caption, MB_OK | MB_SETFOREGROUND); \
|
||||
}
|
||||
|
||||
#define ShowLocalizedMsg(caption, id, args...) \
|
||||
{ \
|
||||
char x_msg[256]; \
|
||||
TCHAR x_buf[1000]; \
|
||||
LoadString(o.hInstance, id, x_buf, sizeof(x_buf)/sizeof(TCHAR)); \
|
||||
mysnprintf(x_msg, x_buf, args); \
|
||||
MessageBox(NULL, x_msg, caption, MB_OK | MB_SETFOREGROUND); \
|
||||
}
|
||||
#define myLoadString(id) \
|
||||
{ \
|
||||
LoadString(o.hInstance, id, buf, sizeof(buf)/sizeof(TCHAR)); \
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Print Debug Message */
|
||||
#define PrintDebug(args...) \
|
||||
{ \
|
||||
char x_msg[256]; \
|
||||
mysnprintf (x_msg, args); \
|
||||
PrintDebugMsg(x_msg); \
|
||||
}
|
||||
|
||||
void PrintDebugMsg(char *msg);
|
||||
void PrintErrorDebug(char *msg);
|
||||
bool init_security_attributes_allow_all (struct security_attributes *obj);
|
||||
#endif
|
||||
|
||||
DWORD GetDllVersion(LPCTSTR lpszDllName);
|
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 "openvpn-gui-res.h"
|
||||
#include <windows.h>
|
||||
|
||||
/* Application Icons */
|
||||
APP_ICON ICON DISCARDABLE "openvpn-gui.ico"
|
||||
APP_ICON_CONNECTED ICON DISCARDABLE "connected.ico"
|
||||
APP_ICON_CONNECTING ICON DISCARDABLE "connecting.ico"
|
||||
APP_ICON_DISCONNECTED ICON DISCARDABLE "disconnected.ico"
|
||||
|
||||
/* About Dialog - designed with lcc-win32 resource editor */
|
||||
IDD_ABOUTDIALOG DIALOG 0, 0, 260, 135
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER
|
||||
CAPTION "About - OpenVPN GUI for Windows"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
PUSHBUTTON "OK", IDOK, 99, 115, 63, 14
|
||||
ICON APP_ICON_CONNECTED, 204, 11, 8, 21, 20
|
||||
LTEXT "", ID_TEXT_OPENVPNGUI, 40, 5, 215, 8
|
||||
LTEXT "Copyright (C) 2004-2005 Mathias Sundman <info@openvpn.se>", 102, 40, 15, 215, 8
|
||||
LTEXT "http://openvpn.se/", 103, 40, 25, 215, 8
|
||||
LTEXT "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.",
|
||||
104, 11, 51, 235, 34
|
||||
LTEXT "Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>", 105, 11, 87, 235, 11
|
||||
LTEXT "http://openvpn.net/", 106, 11, 98, 235, 10
|
||||
END
|
||||
|
||||
/* Passphrase Dialog */
|
||||
IDD_PASSPHRASE DIALOGEX 6, 18, 120, 51
|
||||
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_CENTER | DS_SETFOREGROUND
|
||||
EXSTYLE WS_EX_TOPMOST
|
||||
CAPTION "OpenVPN"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Enter Password:", 201, 6, 6, 100, 10
|
||||
EDITTEXT EDIT_PASSPHRASE, 6, 17, 107, 12, ES_PASSWORD | ES_AUTOHSCROLL
|
||||
PUSHBUTTON "OK", IDOK, 6, 33, 50, 14
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 64, 33, 50, 14
|
||||
END
|
||||
|
||||
/* Auth Username/Password Dialog */
|
||||
IDD_AUTH_PASSWORD DIALOG 6, 18, 160, 62
|
||||
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_CENTER | DS_SETFOREGROUND
|
||||
CAPTION "OpenVPN - User Authentication"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Username:", 0, 6, 9, 50, 10
|
||||
LTEXT "Password:", 0, 6, 26, 50, 10
|
||||
EDITTEXT EDIT_AUTH_USERNAME, 60, 6, 94, 12, ES_AUTOHSCROLL
|
||||
EDITTEXT EDIT_AUTH_PASSWORD, 60, 23, 94, 12, ES_PASSWORD | ES_AUTOHSCROLL
|
||||
PUSHBUTTON "OK", IDOK, 20, 42, 50, 14
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 90, 42, 52, 14
|
||||
END
|
||||
|
||||
/* Status Dialog */
|
||||
IDD_STATUS DIALOG 6, 18, 380, 210
|
||||
STYLE WS_SIZEBOX | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | DS_CENTER
|
||||
CAPTION "OpenVPN"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Connecting...", TEXT_STATUS, 20, 5, 200, 10
|
||||
PUSHBUTTON "Disconnect", ID_DISCONNECT, 50, 190, 50, 14
|
||||
PUSHBUTTON "Reconnect", ID_RESTART, 150, 190, 50, 14
|
||||
PUSHBUTTON "Hide", ID_HIDE, 100, 190, 50, 14
|
||||
LTEXT "", TEXT_CONFIG, 0, 0, 0, 0
|
||||
END
|
||||
|
||||
/* Change Passphrase Dialog */
|
||||
IDD_CHANGEPSW DIALOG 6, 18, 193, 82
|
||||
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER
|
||||
CAPTION "OpenVPN - Change Passphrase"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Old Password:", 171, 6, 9, 85, 10
|
||||
LTEXT "New Password:", 172, 6, 26, 85, 10
|
||||
LTEXT "Confirm New Password:", 173, 6, 42, 85, 10
|
||||
EDITTEXT EDIT_PSW_CURRENT, 95, 6, 90, 12, ES_PASSWORD | ES_AUTOHSCROLL
|
||||
EDITTEXT EDIT_PSW_NEW, 95, 23, 90, 12, ES_PASSWORD | ES_AUTOHSCROLL
|
||||
EDITTEXT EDIT_PSW_NEW2, 95, 39, 90, 12, ES_PASSWORD | ES_AUTOHSCROLL
|
||||
PUSHBUTTON "OK", IDOK, 40, 59, 50, 14
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 103, 59, 50, 14
|
||||
LTEXT "", TEXT_KEYFORMAT, 0, 0, 0, 0
|
||||
LTEXT "", TEXT_KEYFILE, 0, 0, 0, 0
|
||||
END
|
||||
|
||||
/* Proxy Settings Dialog */
|
||||
IDD_PROXY DIALOG 6, 18, 269, 228
|
||||
STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER
|
||||
CAPTION "OpenVPN - Proxy Settings"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
GROUPBOX "", 201, 13, 62, 243, 137
|
||||
AUTORADIOBUTTON "Use OpenVPN Config-file Settings", RB_PROXY_USE_OPENVPN, \
|
||||
20, 12, 200, 10, WS_GROUP | WS_TABSTOP
|
||||
AUTORADIOBUTTON "Use Internet Explorer Settings (manually configured)", \
|
||||
RB_PROXY_USE_IE, 20, 31, 200, 10
|
||||
AUTORADIOBUTTON "Manual Configuration", RB_PROXY_USE_MANUAL, 20, 50, 200, 10
|
||||
AUTORADIOBUTTON "HTTP Proxy", RB_PROXY_HTTP, 20, 74, 59, 10, WS_GROUP | WS_TABSTOP
|
||||
AUTORADIOBUTTON "SOCKS Proxy", RB_PROXY_SOCKS, 20, 147, 67, 10
|
||||
GROUPBOX "", 202, 20, 86, 225, 43
|
||||
LTEXT "Address:", TEXT_PROXY_HTTP_ADDRESS, 27, 98, 41, 10
|
||||
LTEXT "Port:", TEXT_PROXY_HTTP_PORT, 176, 98, 25, 10
|
||||
EDITTEXT EDIT_PROXY_HTTP_ADDRESS, 70, 96, 92, 12, ES_AUTOHSCROLL
|
||||
EDITTEXT EDIT_PROXY_HTTP_PORT, 206, 96, 30, 12, ES_AUTOHSCROLL
|
||||
AUTOCHECKBOX "Prompt for username/password when connecting.", CHECKB_PROXY_AUTH, 27, 112, 183, 10
|
||||
GROUPBOX "", 203, 20, 158, 225, 33
|
||||
LTEXT "Address:", TEXT_PROXY_SOCKS_ADDRESS, 27, 172, 41, 10
|
||||
LTEXT "Port:", TEXT_PROXY_SOCKS_PORT, 176, 172, 20, 10
|
||||
EDITTEXT EDIT_PROXY_SOCKS_ADDRESS, 70, 170, 98, 12, ES_AUTOHSCROLL
|
||||
EDITTEXT EDIT_PROXY_SOCKS_PORT, 206, 170, 30, 12, ES_AUTOHSCROLL
|
||||
PUSHBUTTON "OK", IDOK, 63, 206, 50, 14
|
||||
PUSHBUTTON "Cancel", IDCANCEL, 159, 206, 50, 14
|
||||
END
|
||||
|
||||
/* Proxy Authentication Dialog */
|
||||
IDD_PROXY_AUTH DIALOG 29, 23, 154, 65
|
||||
STYLE DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | DS_CENTER
|
||||
CAPTION "OpenVPN - Proxy Authentication"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Username:", 201, 9, 8, 38, 10
|
||||
EDITTEXT EDIT_PROXY_USERNAME, 49, 5, 94, 12, ES_AUTOHSCROLL
|
||||
LTEXT "Password:", 202, 9, 26, 38, 10
|
||||
EDITTEXT EDIT_PROXY_PASSWORD, 49, 23, 94, 12, ES_PASSWORD | ES_AUTOHSCROLL
|
||||
PUSHBUTTON "OK", IDOK, 58, 43, 40, 14
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
/* About Dialog */
|
||||
TEXT_ABOUT_OPENVPNGUI "OpenVPN GUI v%s - A Windows GUI for OpenVPN"
|
||||
|
||||
/* Tray - Resources */
|
||||
MSG_TIP "OpenVPN GUI "
|
||||
MSG_TIP_CONNECTED "\nConnected to: "
|
||||
MSG_TIP_CONNECTING "\nConnecting to: "
|
||||
MSG_TIP_CONNECTED_SINCE "\nConnected since: "
|
||||
MSG_TIP_ASSIGNED_IP "\nAssigned IP: %s"
|
||||
IDM_TEXT_SERVICE "OpenVPN Service"
|
||||
IDM_TEXT_PROXY "Proxy Settings"
|
||||
IDM_TEXT_ABOUT "About"
|
||||
IDM_TEXT_CLOSE "Exit"
|
||||
IDM_TEXT_CONNECT "Connect"
|
||||
IDM_TEXT_DISCONNECT "Disconnect"
|
||||
IDM_TEXT_STATUS "Show Status"
|
||||
IDM_TEXT_VIEWLOG "View Log"
|
||||
IDM_TEXT_EDITCONFIG "Edit Config"
|
||||
IDM_TEXT_PASSPHRASE "Change Password"
|
||||
IDM_TEXT_SERVICE_START "Start"
|
||||
IDM_TEXT_SERVICE_STOP "Stop"
|
||||
IDM_TEXT_SERVICE_RESTART "Restart"
|
||||
IDM_TEXT_SERVICEONLY_START "Connect"
|
||||
IDM_TEXT_SERVICEONLY_STOP "Disconnect"
|
||||
IDM_TEXT_SERVICEONLY_RESTART "Reconnect"
|
||||
IDM_TEXT_ASK_STOP_SERVICE "Do you want to disconnect (Stop the OpenVPN Service)?"
|
||||
|
||||
/* Logviewer - Resources */
|
||||
ERR_START_LOG_VIEWER "Error starting log-viewer: %s"
|
||||
ERR_START_CONF_EDITOR "Error starting config-editor: %s"
|
||||
|
||||
/* OpenVPN */
|
||||
ERR_TO_MANY_CONFIGS "OpenVPN GUI does not support more than %d configs. Please contact the author if you have the need for more."
|
||||
ERR_CANNOT_CONSTRUCT_LOG "Cannot construct logfile name based on: %s"
|
||||
ERR_ONLY_ONE_CONN_OLD_VERSION "You can only have one connection running at the same time when using an older version on OpenVPN than 2.0-beta6."
|
||||
ERR_STOP_SERV_ON_OLD_VERSION "You cannot use OpenVPN GUI to start a connection while the OpenVPN Service is running (with OpenVPN 1.5/1.6). Stop OpenVPN Service first if you want to use OpenVPN GUI."
|
||||
ERR_CREATE_EVENT "CreateEvent failed on exit event: %s"
|
||||
ERR_UNKNOWN_PRIORITY "Unknown priority name: %s"
|
||||
ERR_LOG_APPEND_BOOL "Log file append flag (given as '%s') must be '0' or '1'"
|
||||
ERR_GET_IE_PROXY_SETTINGS "Unable to get IE proxy settings because:\n%s"
|
||||
ERR_INIT_SEC_DESC "InitializeSecurityDescriptor failed."
|
||||
ERR_SET_SEC_DESC_ACL "SetSecurityDescriptorDacl failed."
|
||||
ERR_CREATE_PIPE_OUTPUT "CreatePipe on hOutputWrite failed."
|
||||
ERR_DUP_HANDLE_ERR_WRITE "DuplicateHandle on hErrorWrite failed."
|
||||
ERR_CREATE_PIPE_INPUT "CreatePipe on hInputRead failed."
|
||||
ERR_DUP_HANDLE_OUTPUT_READ "DuplicateHandle on hOutputRead failed."
|
||||
ERR_DUP_HANDLE_INPUT_WRITE "DuplicateHandle on hInputWrite failed."
|
||||
ERR_CLOSE_HANDLE_TMP "CloseHandle on hOutputReadTmp/hInputWriteTmp failed."
|
||||
ERR_CREATE_PROCESS "CreateProcess failed, exe='%s' cmdline='%s' dir='%s'"
|
||||
ERR_CLOSE_HANDLE "CloseHandle failed."
|
||||
ERR_CREATE_THREAD_STATUS "CreateThread to show Status window Failed."
|
||||
INFO_STATE_WAIT_TERM "Current State: Waiting for OpenVPN to terminate..."
|
||||
ERR_OPEN_LOG_WRITE "Error opening logfile for writing: %s. You probably don't have administrator privileges, which are necessary to run OpenVPN."
|
||||
INFO_STATE_CONNECTED "Current State: Connected"
|
||||
INFO_NOW_CONNECTED "%s is now connected."
|
||||
INFO_ASSIG_IP "Assigned IP: %s"
|
||||
ERR_CERT_EXPIRED "Unable to connect because your certificate has expired or the system time is incorrect."
|
||||
ERR_CERT_NOT_YET_VALID "Unable to connect because your certificate is not yet valid. Check that your system time is correct."
|
||||
INFO_STATE_RECONNECTING "Current State: Reconnecting"
|
||||
INFO_STATE_DISCONNECTED "Current State: Disconnected"
|
||||
INFO_CONN_TERMINATED "Connection to %s was terminated."
|
||||
INFO_STATE_FAILED "Current State: Failed to connect"
|
||||
INFO_CONN_FAILED "Connecting to %s has failed."
|
||||
INFO_STATE_FAILED_RECONN "Current State: Failed to reconnect"
|
||||
INFO_RECONN_FAILED "ReConnecting to %s has failed."
|
||||
INFO_STATE_SUSPENDED "Current State: Suspended"
|
||||
ERR_READ_STDOUT_PIPE "Error reading from OpenVPN StdOut Pipe."
|
||||
ERR_CREATE_RICHED_LOGWINDOW "Creating RichEdit LogWindow Failed!!"
|
||||
ERR_SET_SIZE "Set Size failed!"
|
||||
ERR_AUTOSTART_CONF_NOT_FOUND "Cannot find requested config to autostart: %s"
|
||||
ERR_VERSION_CREATE_EVENT "CreateEvent() failed when checking openvpn version."
|
||||
ERR_CREATE_PIPE_INPUT_READ "CreatePipe on hInputRead failed."
|
||||
INFO_STATE_CONNECTING "Current State: Connecting"
|
||||
INFO_CONNECTION_XXX "OpenVPN Connection (%s)"
|
||||
ERR_CREATE_THREAD_READ_STDOUT "CreateThread to read openvpn process stdout failed."
|
||||
INFO_STATE_CONN_SCRIPT "Current State: Running Connect Script"
|
||||
INFO_STATE_DISCONN_SCRIPT "Current State: Running Disconnect Script"
|
||||
ERR_RUN_CONN_SCRIPT "Error running Connect Script: %s"
|
||||
ERR_GET_EXIT_CODE "Failed to get ExitCode of Connect Script (%s)"
|
||||
ERR_CONN_SCRIPT_FAILED "Connect Script failed. (exitcode=%ld)"
|
||||
ERR_RUN_CONN_SCRIPT_TIMEOUT "Connect Script failed. TimeOut after %d sec."
|
||||
ERR_CONFIG_ALREADY_EXIST "There already exist a config file named '%s'. You cannot " \
|
||||
"have multiple config files with the same name, even if " \
|
||||
"they reside in diffrent folders."
|
||||
/* main - Resources */
|
||||
ERR_OPEN_DEBUG_FILE "Error opening debug file (%s) for output."
|
||||
ERR_LOAD_RICHED20 "Could not load RICHED20.DLL."
|
||||
ERR_SHELL_DLL_VERSION "Your shell32.dll version is to low (0x%lx). You need at least version 5.0."
|
||||
ERR_GUI_ALREADY_RUNNING "OpenVPN GUI is already running."
|
||||
INFO_SERVICE_STARTED "OpenVPN Service started."
|
||||
INFO_SERVICE_STOPPED "OpenVPN Service stopped."
|
||||
INFO_ACTIVE_CONN_EXIT "There are still active connections that will be closed if you exit OpenVPN GUI." \
|
||||
"\n\nAre you sure you want to exit?"
|
||||
INFO_SERVICE_ACTIVE_EXIT "You are currently connected (the OpenVPN Service is running). " \
|
||||
"You will stay connected even if you exit OpenVPN GUI.\n\n" \
|
||||
"Do you want to proceed and exit OpenVPN GUI?"
|
||||
ERR_OPTION_LOG_IN_CONFIG "You have ""log"" or ""log-append"" in your OpenVPN config file. These options " \
|
||||
"should not be used with OpenVPN GUI as they prevents OpenVPN GUI from reading " \
|
||||
"the log output of OpenVPN which is necessary for correct operation of OpenVPN " \
|
||||
"GUI. The log is always written to a logfile when OpenVPN GUI is beeing used " \
|
||||
"anyway, so you should remove this option.\n\nDo you want to proceed connecting " \
|
||||
"anyway?"
|
||||
|
||||
/* options - Resources */
|
||||
INFO_USAGE "--help\t\t\t: Show this message.\n" \
|
||||
"--connect cnn \t\t: Connect to ""cnn"" at startup. (extension must be included)\n" \
|
||||
"\t\t\t Example: openvpn-gui --connect office.ovpn\n" \
|
||||
"\n" \
|
||||
"Options to override registry settings:\n" \
|
||||
"--exe_path\t\t: Path to openvpn.exe.\n" \
|
||||
"--config_dir\t\t: Path to dir to search for config files in.\n" \
|
||||
"--ext_string\t\t: Extension on config files.\n" \
|
||||
"--log_dir\t\t\t: Path to dir where log files will be saved.\n" \
|
||||
"--priority_string\t\t: Priority string (See install.txt for more info).\n" \
|
||||
"--append_string\t\t: 1=Append to log file. 0=Truncate logfile when connecting.\n" \
|
||||
"--log_viewer\t\t: Path to log viewer.\n" \
|
||||
"--editor\t\t\t: Path to config editor.\n" \
|
||||
"--allow_edit\t\t: 1=Show Edit Config menu item.\n" \
|
||||
"--allow_service\t\t: 1=Show Service control menu.\n" \
|
||||
"--allow_password\t\t: 1=Show Change Password menu item.\n" \
|
||||
"--allow_proxy\t\t: 1=Show Proxy Settings menu.\n" \
|
||||
"--show_balloon\t\t: 0=Never, 1=At initial connect, 2=At every re-connect.\n" \
|
||||
"--service_only\t\t: 1=Enable Service Only mode.\n" \
|
||||
"--silent_connection\t\t: 1=Do not show the status dialog while connecting.\n" \
|
||||
"--show_script_window\t: 0=Hide Script execution window, 1=Show it.\n" \
|
||||
"--passphrase_attempts\t: Number of passphrase attempts to allow.\n" \
|
||||
"--connectscript_timeout\t: Time to wait for connect script to finish.\n" \
|
||||
"--disconnectscript_timeout\t: Time to wait for disconnect script to finish.\n" \
|
||||
"--preconnectscript_timeout\t: Time to wait for preconnect script to finish.\n"
|
||||
|
||||
INFO_USAGECAPTION "OpenVPN GUI Usage"
|
||||
ERR_BAD_PARAMETER "I'm trying to parse ""%s"" as an --option parameter " \
|
||||
"but I don't see a leading '--'"
|
||||
ERR_BAD_OPTION "Options error: Unrecognized option or missing parameter(s): --%s\n" \
|
||||
"Use openvpn-gui --help for more info."
|
||||
|
||||
/* passphrase - Resources */
|
||||
ERR_CREATE_PASS_THREAD "CreateThread to show ChangePassphrase dialog failed."
|
||||
INFO_CHANGE_PWD "Change Password (%s)"
|
||||
ERR_PWD_DONT_MATCH "The passwords you typed do not match. Try again."
|
||||
ERR_PWD_TO_SHORT "Your new password must be at least %d characters long."
|
||||
INFO_EMPTY_PWD "Are you sure you want to set an EMPTY password?"
|
||||
ERR_UNKNOWN_KEYFILE_FORMAT "Unknown keyfile format."
|
||||
ERR_OPEN_PRIVATE_KEY_FILE "Error opening private key file (%s)."
|
||||
ERR_OLD_PWD_INCORRECT "The old password is incorrect."
|
||||
ERR_OPEN_WRITE_KEY "Error opening private key file for writing (%s)."
|
||||
ERR_WRITE_NEW_KEY "Error writing new private key file (%s)."
|
||||
INFO_PWD_CHANGED "Your password has been changed."
|
||||
ERR_READ_PKCS12 "Error reading PKCS #12 file (%s)."
|
||||
ERR_CREATE_PKCS12 "Error creating new PKCS #12 object. Change Password has failed."
|
||||
ERR_OPEN_CONFIG "Could not open config file for reading: (%s)"
|
||||
ERR_ONLY_ONE_KEY_OPTION "You cannot have more than one ""key"" option in your config."
|
||||
ERR_ONLY_KEY_OR_PKCS12 "You cannot have both ""key"" and ""pkcs12"" options in your config."
|
||||
ERR_ONLY_ONE_PKCS12_OPTION "You cannot have more than one ""pkcs12"" option in your config."
|
||||
ERR_MUST_HAVE_KEY_OR_PKCS12 "Your config file does not contain any ""key"" or ""pkcs12"" option."
|
||||
ERR_KEY_FILENAME_TO_LONG "Your key filename in the config is too long!"
|
||||
ERR_PASSPHRASE2STDIN "Error passing passphrase to stdin."
|
||||
ERR_AUTH_USERNAME2STDIN "Error passing auth username to stdin."
|
||||
ERR_AUTH_PASSWORD2STDIN "Error passing auth password to stdin."
|
||||
ERR_CR2STDIN "Error passing CR to stdin."
|
||||
ERR_INVALID_CHARS_IN_PSW "Your new password contains non-valid characters. " \
|
||||
"Please choose another one."
|
||||
/* proxy */
|
||||
ERR_HTTP_PROXY_ADDRESS "You must specify a HTTP proxy address."
|
||||
ERR_HTTP_PROXY_PORT "You must specify a HTTP proxy port."
|
||||
ERR_HTTP_PROXY_PORT_RANGE "You must specify a HTTP proxy port between 1-65535"
|
||||
ERR_SOCKS_PROXY_ADDRESS "You must specify a SOCKS proxy address."
|
||||
ERR_SOCKS_PROXY_PORT "You must specify a SOCKS proxy port."
|
||||
ERR_SOCKS_PROXY_PORT_RANGE "You must specify a SOCKS proxy port between 1-65535"
|
||||
ERR_CREATE_REG_HKCU_KEY "Error creating ""HKEY_CURRENT_USER\\%s"" key."
|
||||
ERR_GET_TEMP_PATH "Error determining TempPath with GetTempPath(). Using ""C:\\"" instead."
|
||||
ERR_CREATE_AUTH_FILE "Error creating AUTH file. (%s)"
|
||||
|
||||
/* service */
|
||||
ERR_OPEN_SCMGR_ADMIN "OpenSCManager failed. You need Administrator rights to start a service."
|
||||
ERR_OPEN_VPN_SERVICE "Failed to open ""OpenVPNService"""
|
||||
ERR_START_SERVICE "Failed to start ""OpenVPNService"""
|
||||
ERR_QUERY_SERVICE "Failed to query service status."
|
||||
ERR_SERVICE_START_FAILED "OpenVPN Service failed to start."
|
||||
ERR_OPEN_SCMGR "OpenSCManager failed (%d)"
|
||||
ERR_STOP_SERVICE "Failed to stop OpenVPN Service"
|
||||
INFO_RESTARTED "OpenVPN Service Restarted."
|
||||
|
||||
/* registry */
|
||||
ERR_GET_WINDOWS_DIR "Error getting Windows Directory."
|
||||
ERR_GET_PROGRAM_DIR "Error getting ""Program"" folder name."
|
||||
ERR_OPEN_REGISTRY "Error opening registry for reading (HKLM\\SOFTWARE\\OpenVPN).\n " \
|
||||
"OpenVPN is probably not installed"
|
||||
ERR_READING_REGISTRY "Error reading registry value (HKLM\\SOFTWARE\\OpenVPN)."
|
||||
ERR_PASSPHRASE_ATTEMPTS "Registry value ""passphrase_attempts"" must be a number between 1 and 9."
|
||||
ERR_CONN_SCRIPT_TIMEOUT "Registry value ""connectscript_timeout"" must be a number between 0 and 99."
|
||||
ERR_DISCONN_SCRIPT_TIMEOUT "Registry value ""disconnectscript_timeout"" must be a number between 1 and 99."
|
||||
ERR_PRECONN_SCRIPT_TIMEOUT "Registry value ""preconnectscript_timeout"" must be a number between 1 and 99."
|
||||
ERR_CREATE_REG_KEY "Error creating HKLM\\SOFTWARE\\OpenVPN-GUI key."
|
||||
ERR_OPEN_WRITE_REG "Failed to open the registry for writing. You need to run this application " \
|
||||
"once as Administrator to update the registry."
|
||||
ERR_READ_SET_KEY "Error reading and setting registry key ""%s""."
|
||||
ERR_WRITE_REGVALUE "Error writing registry value ""HKEY_CURRENT_USER\\%s\\%s""."
|
||||
END
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
/* Icons */
|
||||
#define APP_ICON 90
|
||||
#define APP_ICON_CONNECTED 91
|
||||
#define APP_ICON_CONNECTING 92
|
||||
#define APP_ICON_DISCONNECTED 93
|
||||
|
||||
/* About Dialog */
|
||||
#define IDD_ABOUTDIALOG 100
|
||||
#define ID_TEXT_OPENVPNGUI 101
|
||||
#define TEXT_ABOUT_OPENVPNGUI 102
|
||||
|
||||
/* Ask for Passphrase Dialog */
|
||||
#define IDD_PASSPHRASE 150
|
||||
#define EDIT_PASSPHRASE 151
|
||||
|
||||
/* Status Dialog */
|
||||
#define IDD_STATUS 160
|
||||
#define TEXT_STATUS 161
|
||||
#define EDIT_LOG 162
|
||||
#define ID_DISCONNECT 163
|
||||
#define ID_RESTART 164
|
||||
#define ID_HIDE 165
|
||||
/* A hidden textbox used to pass the config nr so dialog knows
|
||||
* which connection to cancel. If anyone knows of another way
|
||||
* to pass a variable to dialog, please let me know.
|
||||
*/
|
||||
#define TEXT_CONFIG 166
|
||||
|
||||
/* Change Passphrase Dialog */
|
||||
#define IDD_CHANGEPSW 170
|
||||
#define EDIT_PSW_CURRENT 174
|
||||
#define EDIT_PSW_NEW 175
|
||||
#define EDIT_PSW_NEW2 176
|
||||
#define TEXT_KEYFILE 177
|
||||
#define TEXT_KEYFORMAT 178
|
||||
|
||||
/* Auth Username/Password Dialog */
|
||||
#define IDD_AUTH_PASSWORD 180
|
||||
#define EDIT_AUTH_USERNAME 181
|
||||
#define EDIT_AUTH_PASSWORD 182
|
||||
|
||||
/* Proxy Settings Dialog */
|
||||
#define IDD_PROXY 200
|
||||
#define RB_PROXY_USE_OPENVPN 210
|
||||
#define RB_PROXY_USE_IE 211
|
||||
#define RB_PROXY_USE_MANUAL 212
|
||||
#define RB_PROXY_HTTP 213
|
||||
#define EDIT_PROXY_HTTP_ADDRESS 214
|
||||
#define EDIT_PROXY_HTTP_PORT 215
|
||||
#define TEXT_PROXY_HTTP_ADDRESS 216
|
||||
#define TEXT_PROXY_HTTP_PORT 217
|
||||
#define CHECKB_PROXY_AUTH 218
|
||||
#define RB_PROXY_SOCKS 219
|
||||
#define EDIT_PROXY_SOCKS_ADDRESS 220
|
||||
#define EDIT_PROXY_SOCKS_PORT 221
|
||||
#define TEXT_PROXY_SOCKS_ADDRESS 222
|
||||
#define TEXT_PROXY_SOCKS_PORT 223
|
||||
|
||||
/* Proxy Auth Dialog */
|
||||
#define IDD_PROXY_AUTH 250
|
||||
#define EDIT_PROXY_USERNAME 251
|
||||
#define EDIT_PROXY_PASSWORD 252
|
||||
|
||||
/* Tray - Resources */
|
||||
#define MSG_TIP 1001
|
||||
#define MSG_TIP_CONNECTED 1002
|
||||
#define MSG_TIP_CONNECTING 1003
|
||||
#define MSG_TIP_CONNECTED_SINCE 1004
|
||||
#define MSG_TIP_ASSIGNED_IP 1005
|
||||
#define IDM_TEXT_SERVICE 1006
|
||||
#define IDM_TEXT_PROXY 1007
|
||||
#define IDM_TEXT_ABOUT 1008
|
||||
#define IDM_TEXT_CLOSE 1009
|
||||
#define IDM_TEXT_CONNECT 1010
|
||||
#define IDM_TEXT_DISCONNECT 1011
|
||||
#define IDM_TEXT_STATUS 1012
|
||||
#define IDM_TEXT_VIEWLOG 1013
|
||||
#define IDM_TEXT_EDITCONFIG 1014
|
||||
#define IDM_TEXT_PASSPHRASE 1015
|
||||
#define IDM_TEXT_SERVICE_START 1016
|
||||
#define IDM_TEXT_SERVICE_STOP 1017
|
||||
#define IDM_TEXT_SERVICE_RESTART 1018
|
||||
#define IDM_TEXT_SERVICEONLY_START 1019
|
||||
#define IDM_TEXT_SERVICEONLY_STOP 1020
|
||||
#define IDM_TEXT_SERVICEONLY_RESTART 1021
|
||||
#define IDM_TEXT_ASK_STOP_SERVICE 1022
|
||||
|
||||
/* LogViewer */
|
||||
#define ERR_START_LOG_VIEWER 1101
|
||||
#define ERR_START_CONF_EDITOR 1102
|
||||
|
||||
/* OpenVpn */
|
||||
#define ERR_TO_MANY_CONFIGS 1201
|
||||
#define ERR_CANNOT_CONSTRUCT_LOG 1202
|
||||
#define ERR_ONLY_ONE_CONN_OLD_VERSION 1203
|
||||
#define ERR_STOP_SERV_ON_OLD_VERSION 1204
|
||||
#define ERR_CREATE_EVENT 1205
|
||||
#define ERR_UNKNOWN_PRIORITY 1206
|
||||
#define ERR_LOG_APPEND_BOOL 1207
|
||||
#define ERR_GET_IE_PROXY_SETTINGS 1208
|
||||
#define ERR_INIT_SEC_DESC 1209
|
||||
#define ERR_SET_SEC_DESC_ACL 1210
|
||||
#define ERR_CREATE_PIPE_OUTPUT 1211
|
||||
#define ERR_DUP_HANDLE_ERR_WRITE 1212
|
||||
#define ERR_CREATE_PIPE_INPUT 1213
|
||||
#define ERR_DUP_HANDLE_OUTPUT_READ 1214
|
||||
#define ERR_DUP_HANDLE_INPUT_WRITE 1215
|
||||
#define ERR_CLOSE_HANDLE_TMP 1216
|
||||
#define ERR_CREATE_PROCESS 1217
|
||||
#define ERR_CLOSE_HANDLE 1218
|
||||
#define ERR_CREATE_THREAD_STATUS 1219
|
||||
#define INFO_STATE_WAIT_TERM 1220
|
||||
#define ERR_OPEN_LOG_WRITE 1221
|
||||
#define INFO_STATE_CONNECTED 1222
|
||||
#define INFO_NOW_CONNECTED 1223
|
||||
#define INFO_ASSIG_IP 1224
|
||||
#define ERR_CERT_EXPIRED 1225
|
||||
#define ERR_CERT_NOT_YET_VALID 1226
|
||||
#define INFO_STATE_RECONNECTING 1227
|
||||
#define INFO_STATE_DISCONNECTED 1228
|
||||
#define INFO_CONN_TERMINATED 1229
|
||||
#define INFO_STATE_FAILED 1230
|
||||
#define INFO_CONN_FAILED 1231
|
||||
#define INFO_STATE_FAILED_RECONN 1232
|
||||
#define INFO_RECONN_FAILED 1233
|
||||
#define INFO_STATE_SUSPENDED 1234
|
||||
#define ERR_READ_STDOUT_PIPE 1235
|
||||
#define ERR_CREATE_RICHED_LOGWINDOW 1236
|
||||
#define ERR_SET_SIZE 1237
|
||||
#define ERR_AUTOSTART_CONF_NOT_FOUND 1238
|
||||
#define ERR_VERSION_CREATE_EVENT 1239
|
||||
#define ERR_CREATE_PIPE_INPUT_READ 1240
|
||||
#define INFO_STATE_CONNECTING 1241
|
||||
#define INFO_CONNECTION_XXX 1242
|
||||
#define ERR_CREATE_THREAD_READ_STDOUT 1243
|
||||
#define INFO_STATE_CONN_SCRIPT 1244
|
||||
#define INFO_STATE_DISCONN_SCRIPT 1245
|
||||
#define ERR_RUN_CONN_SCRIPT 1246
|
||||
#define ERR_GET_EXIT_CODE 1247
|
||||
#define ERR_CONN_SCRIPT_FAILED 1248
|
||||
#define ERR_RUN_CONN_SCRIPT_TIMEOUT 1249
|
||||
#define ERR_OPTION_LOG_IN_CONFIG 1250
|
||||
#define ERR_CONFIG_ALREADY_EXIST 1251
|
||||
|
||||
/* main */
|
||||
#define ERR_OPEN_DEBUG_FILE 1301
|
||||
#define ERR_LOAD_RICHED20 1302
|
||||
#define ERR_SHELL_DLL_VERSION 1303
|
||||
#define ERR_GUI_ALREADY_RUNNING 1304
|
||||
#define INFO_SERVICE_STARTED 1305
|
||||
#define INFO_SERVICE_STOPPED 1306
|
||||
#define INFO_ACTIVE_CONN_EXIT 1307
|
||||
#define INFO_SERVICE_ACTIVE_EXIT 1308
|
||||
|
||||
/* options */
|
||||
#define INFO_USAGE 1401
|
||||
#define INFO_USAGECAPTION 1402
|
||||
#define ERR_BAD_PARAMETER 1403
|
||||
#define ERR_BAD_OPTION 1404
|
||||
|
||||
/* passphrase */
|
||||
#define ERR_CREATE_PASS_THREAD 1501
|
||||
#define INFO_CHANGE_PWD 1502
|
||||
#define ERR_PWD_DONT_MATCH 1503
|
||||
#define ERR_PWD_TO_SHORT 1504
|
||||
#define INFO_EMPTY_PWD 1505
|
||||
#define ERR_UNKNOWN_KEYFILE_FORMAT 1506
|
||||
#define ERR_OPEN_PRIVATE_KEY_FILE 1507
|
||||
#define ERR_OLD_PWD_INCORRECT 1508
|
||||
#define ERR_OPEN_WRITE_KEY 1509
|
||||
#define ERR_WRITE_NEW_KEY 1510
|
||||
#define INFO_PWD_CHANGED 1511
|
||||
#define ERR_READ_PKCS12 1512
|
||||
#define ERR_CREATE_PKCS12 1513
|
||||
#define ERR_OPEN_CONFIG 1514
|
||||
#define ERR_ONLY_ONE_KEY_OPTION 1515
|
||||
#define ERR_ONLY_KEY_OR_PKCS12 1516
|
||||
#define ERR_ONLY_ONE_PKCS12_OPTION 1517
|
||||
#define ERR_MUST_HAVE_KEY_OR_PKCS12 1518
|
||||
#define ERR_KEY_FILENAME_TO_LONG 1519
|
||||
#define ERR_PASSPHRASE2STDIN 1520
|
||||
#define ERR_CR2STDIN 1521
|
||||
#define ERR_AUTH_USERNAME2STDIN 1522
|
||||
#define ERR_AUTH_PASSWORD2STDIN 1523
|
||||
#define ERR_INVALID_CHARS_IN_PSW 1524
|
||||
|
||||
|
||||
/* proxy */
|
||||
#define ERR_HTTP_PROXY_ADDRESS 1601
|
||||
#define ERR_HTTP_PROXY_PORT 1602
|
||||
#define ERR_HTTP_PROXY_PORT_RANGE 1603
|
||||
#define ERR_SOCKS_PROXY_ADDRESS 1604
|
||||
#define ERR_SOCKS_PROXY_PORT 1605
|
||||
#define ERR_SOCKS_PROXY_PORT_RANGE 1606
|
||||
#define ERR_CREATE_REG_HKCU_KEY 1607
|
||||
#define ERR_GET_TEMP_PATH 1608
|
||||
#define ERR_CREATE_AUTH_FILE 1609
|
||||
|
||||
/* service */
|
||||
#define ERR_OPEN_SCMGR_ADMIN 1701
|
||||
#define ERR_OPEN_VPN_SERVICE 1702
|
||||
#define ERR_START_SERVICE 1703
|
||||
#define ERR_QUERY_SERVICE 1704
|
||||
#define ERR_SERVICE_START_FAILED 1705
|
||||
#define ERR_OPEN_SCMGR 1706
|
||||
#define ERR_STOP_SERVICE 1707
|
||||
#define INFO_RESTARTED 1708
|
||||
|
||||
/* registry */
|
||||
#define ERR_GET_WINDOWS_DIR 1801
|
||||
#define ERR_GET_PROGRAM_DIR 1802
|
||||
#define ERR_OPEN_REGISTRY 1803
|
||||
#define ERR_READING_REGISTRY 1804
|
||||
#define ERR_PASSPHRASE_ATTEMPTS 1805
|
||||
#define ERR_CONN_SCRIPT_TIMEOUT 1806
|
||||
#define ERR_DISCONN_SCRIPT_TIMEOUT 1807
|
||||
#define ERR_PRECONN_SCRIPT_TIMEOUT 1808
|
||||
#define ERR_CREATE_REG_KEY 1809
|
||||
#define ERR_OPEN_WRITE_REG 1810
|
||||
#define ERR_READ_SET_KEY 1811
|
||||
#define ERR_WRITE_REGVALUE 1812
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
|
@ -0,0 +1,974 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*
|
||||
* Parts of this sourcefile is taken from openvpnserv.c from the
|
||||
* OpenVPN source, with approval from the author, James Yonan
|
||||
* <jim@yonan.net>.
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include "tray.h"
|
||||
#include "main.h"
|
||||
#include "openvpn.h"
|
||||
#include "openvpn_monitor_process.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
#include "options.h"
|
||||
#include "scripts.h"
|
||||
#include "viewlog.h"
|
||||
#include "proxy.h"
|
||||
#include "passphrase.h"
|
||||
#include <richedit.h>
|
||||
|
||||
extern struct options o;
|
||||
|
||||
/*
|
||||
* Creates a unique exit_event name based on the
|
||||
* config file number.
|
||||
*/
|
||||
int CreateExitEvent(int config)
|
||||
{
|
||||
o.cnn[config].exit_event = NULL;
|
||||
if (o.oldversion == 1)
|
||||
{
|
||||
mysnprintf(o.cnn[config].exit_event_name, "openvpn_exit");
|
||||
o.cnn[config].exit_event = CreateEvent (NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
o.cnn[config].exit_event_name);
|
||||
if (o.cnn[config].exit_event == NULL)
|
||||
{
|
||||
if (GetLastError() == ERROR_ACCESS_DENIED)
|
||||
{
|
||||
/* service mustn't be running, while using old version */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_STOP_SERV_ON_OLD_VERSION, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* error creating exit event */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_EVENT, o.cnn[config].exit_event_name);
|
||||
}
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf(o.cnn[config].exit_event_name, "openvpngui_exit_event_%d",config);
|
||||
o.cnn[config].exit_event = CreateEvent (NULL,
|
||||
TRUE,
|
||||
FALSE,
|
||||
o.cnn[config].exit_event_name);
|
||||
if (o.cnn[config].exit_event == NULL)
|
||||
{
|
||||
/* error creating exit event */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_EVENT, o.cnn[config].exit_event_name);
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set priority based on the registry or cmd-line value
|
||||
*/
|
||||
int SetProcessPriority(DWORD *priority)
|
||||
{
|
||||
|
||||
/* set process priority */
|
||||
*priority = NORMAL_PRIORITY_CLASS;
|
||||
if (!strcmp (o.priority_string, "IDLE_PRIORITY_CLASS"))
|
||||
*priority = IDLE_PRIORITY_CLASS;
|
||||
else if (!strcmp (o.priority_string, "BELOW_NORMAL_PRIORITY_CLASS"))
|
||||
*priority = BELOW_NORMAL_PRIORITY_CLASS;
|
||||
else if (!strcmp (o.priority_string, "NORMAL_PRIORITY_CLASS"))
|
||||
*priority = NORMAL_PRIORITY_CLASS;
|
||||
else if (!strcmp (o.priority_string, "ABOVE_NORMAL_PRIORITY_CLASS"))
|
||||
*priority = ABOVE_NORMAL_PRIORITY_CLASS;
|
||||
else if (!strcmp (o.priority_string, "HIGH_PRIORITY_CLASS"))
|
||||
*priority = HIGH_PRIORITY_CLASS;
|
||||
else
|
||||
{
|
||||
/* unknown priority */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_UNKNOWN_PRIORITY, o.priority_string);
|
||||
return (false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Launch an OpenVPN process
|
||||
*/
|
||||
int StartOpenVPN(int config)
|
||||
{
|
||||
|
||||
HANDLE hOutputReadTmp = NULL;
|
||||
HANDLE hOutputRead = NULL;
|
||||
HANDLE hOutputWrite = NULL;
|
||||
HANDLE hInputWriteTmp = NULL;
|
||||
HANDLE hInputRead = NULL;
|
||||
HANDLE hInputWrite = NULL;
|
||||
HANDLE hErrorWrite = NULL;
|
||||
|
||||
HANDLE hThread;
|
||||
DWORD IDThread;
|
||||
DWORD priority;
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
char proxy_string[100];
|
||||
char msg[200];
|
||||
int i, is_connected=0;
|
||||
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
|
||||
/* If oldversion, allow only ONE connection */
|
||||
if (o.oldversion == 1)
|
||||
{
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if ((o.cnn[i].connect_status != DISCONNECTED) &&
|
||||
(o.cnn[i].connect_status != DISCONNECTING))
|
||||
{
|
||||
is_connected=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_connected)
|
||||
{
|
||||
/* only one simultanious connection on old version */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_ONE_CONN_OLD_VERSION, "");
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Warn if "log" or "log-append" option is found in config file */
|
||||
if ((ConfigFileOptionExist(config, "log ")) ||
|
||||
(ConfigFileOptionExist(config, "log-append ")))
|
||||
{
|
||||
TCHAR buf[1000];
|
||||
myLoadString(ERR_OPTION_LOG_IN_CONFIG);
|
||||
if (MessageBox(NULL, buf, GUI_NAME, MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING) != IDYES)
|
||||
return(false);
|
||||
}
|
||||
|
||||
/* Clear connection unique vars */
|
||||
o.cnn[config].failed_psw = 0;
|
||||
CLEAR (o.cnn[config].ip);
|
||||
|
||||
/* Create our exit event */
|
||||
if (!CreateExitEvent(config))
|
||||
return(false);
|
||||
|
||||
/* set process priority */
|
||||
if (!SetProcessPriority(&priority))
|
||||
goto failed;
|
||||
|
||||
/* Check that log append flag has a valid value */
|
||||
if ((o.append_string[0] != '0') && (o.append_string[0] != '1'))
|
||||
{
|
||||
/* append_log must be 0 or 1 */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_LOG_APPEND_BOOL, o.append_string);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* construct proxy string to append to command line */
|
||||
ConstructProxyCmdLine(proxy_string, sizeof(proxy_string));
|
||||
|
||||
/* construct command line */
|
||||
if (o.oldversion == 1)
|
||||
{
|
||||
mysnprintf (command_line, "openvpn --config \"%s\" %s",
|
||||
o.cnn[config].config_file, proxy_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf (command_line, "openvpn --service %s 0 --config \"%s\" %s",
|
||||
o.cnn[config].exit_event_name,
|
||||
o.cnn[config].config_file,
|
||||
proxy_string);
|
||||
}
|
||||
|
||||
|
||||
/* Make security attributes struct for logfile handle so it can
|
||||
be inherited. */
|
||||
sa.nLength = sizeof (sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
sa.bInheritHandle = TRUE;
|
||||
if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
|
||||
{
|
||||
/* Init Sec. Desc. failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_INIT_SEC_DESC, "");
|
||||
goto failed;
|
||||
}
|
||||
if (!SetSecurityDescriptorDacl (&sd, TRUE, NULL, FALSE))
|
||||
{
|
||||
/* set Dacl failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_SET_SEC_DESC_ACL, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
/* Create the child output pipe. */
|
||||
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
|
||||
{
|
||||
/* CreatePipe failed. */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_OUTPUT, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// Create a duplicate of the output write handle for the std error
|
||||
// write handle. This is necessary in case the child application
|
||||
// closes one of its std output handles.
|
||||
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
|
||||
GetCurrentProcess(),&hErrorWrite,0,
|
||||
TRUE,DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* DuplicateHandle failed. */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_ERR_WRITE, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// Create the child input pipe.
|
||||
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
|
||||
{
|
||||
/* CreatePipe failed. */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_INPUT, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// Create new output read handle and the input write handles. Set
|
||||
// the Properties to FALSE. Otherwise, the child inherits the
|
||||
// properties and, as a result, non-closeable handles to the pipes
|
||||
// are created.
|
||||
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
|
||||
GetCurrentProcess(),
|
||||
&hOutputRead, // Address of new handle.
|
||||
0,FALSE, // Make it uninheritable.
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* Duplicate Handle failed. */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_OUTPUT_READ, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
|
||||
GetCurrentProcess(),
|
||||
&hInputWrite, // Address of new handle.
|
||||
0,FALSE, // Make it uninheritable.
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* DuplicateHandle failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_INPUT_WRITE, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Close inheritable copies of the handles */
|
||||
if (!CloseHandle(hOutputReadTmp) || !CloseHandle(hInputWriteTmp))
|
||||
{
|
||||
/* Close Handle failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CLOSE_HANDLE_TMP, "");
|
||||
CloseHandle (o.cnn[config].exit_event);
|
||||
return(0);
|
||||
}
|
||||
hOutputReadTmp=NULL;
|
||||
hInputWriteTmp=NULL;
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = STARTF_USESTDHANDLES;
|
||||
start_info.hStdInput = hInputRead;
|
||||
start_info.hStdOutput = hOutputWrite;
|
||||
start_info.hStdError = hErrorWrite;
|
||||
|
||||
/* Run Pre-connect script */
|
||||
RunPreconnectScript(config);
|
||||
|
||||
/* create an OpenVPN process for one config file */
|
||||
if (!CreateProcess(o.exe_path,
|
||||
command_line,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
priority | CREATE_NO_WINDOW,
|
||||
NULL,
|
||||
o.cnn[config].config_dir,
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
/* CreateProcess failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_PROCESS,
|
||||
o.exe_path,
|
||||
command_line,
|
||||
o.cnn[config].config_dir);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
/* close unneeded handles */
|
||||
Sleep (250); /* try to prevent race if we close logfile
|
||||
handle before child process DUPs it */
|
||||
|
||||
if(!CloseHandle (proc_info.hThread) ||
|
||||
!CloseHandle (hOutputWrite) ||
|
||||
!CloseHandle (hInputRead) ||
|
||||
!CloseHandle (hErrorWrite))
|
||||
{
|
||||
/* CloseHandle failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CLOSE_HANDLE, "");
|
||||
CloseHandle (o.cnn[config].exit_event);
|
||||
return(false);
|
||||
}
|
||||
hOutputWrite = NULL;
|
||||
hInputRead = NULL;
|
||||
hErrorWrite = NULL;
|
||||
|
||||
/* Save StdIn and StdOut handles in our options struct */
|
||||
o.cnn[config].hStdIn = hInputWrite;
|
||||
o.cnn[config].hStdOut = hOutputRead;
|
||||
|
||||
/* Save Process Handle */
|
||||
o.cnn[config].hProcess=proc_info.hProcess;
|
||||
|
||||
|
||||
/* Start Thread to show Status Dialog */
|
||||
hThread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) ThreadOpenVPNStatus,
|
||||
(int *) config, // pass config nr
|
||||
0, &IDThread);
|
||||
if (hThread == NULL)
|
||||
{
|
||||
/* CreateThread failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_THREAD_STATUS, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
||||
return(true);
|
||||
|
||||
failed:
|
||||
if (o.cnn[config].exit_event) CloseHandle (o.cnn[config].exit_event);
|
||||
if (hOutputWrite) CloseHandle (hOutputWrite);
|
||||
if (hOutputRead) CloseHandle (hOutputRead);
|
||||
if (hInputWrite) CloseHandle (hInputWrite);
|
||||
if (hInputRead) CloseHandle (hInputRead);
|
||||
if (hErrorWrite) CloseHandle (hOutputWrite);
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void StopOpenVPN(int config)
|
||||
{
|
||||
int i;
|
||||
TCHAR buf[1000];
|
||||
|
||||
o.cnn[config].connect_status = DISCONNECTING;
|
||||
|
||||
if (o.cnn[config].exit_event) {
|
||||
/* Run Disconnect script */
|
||||
RunDisconnectScript(config, false);
|
||||
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
|
||||
SetMenuStatus(config, DISCONNECTING);
|
||||
myLoadString(INFO_STATE_WAIT_TERM);
|
||||
/* UserInfo: waiting for OpenVPN termination... */
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetEvent(o.cnn[config].exit_event);
|
||||
}
|
||||
}
|
||||
|
||||
void SuspendOpenVPN(int config)
|
||||
{
|
||||
int i;
|
||||
TCHAR buf[1000];
|
||||
|
||||
o.cnn[config].connect_status = SUSPENDING;
|
||||
o.cnn[config].restart = true;
|
||||
|
||||
if (o.cnn[config].exit_event) {
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
|
||||
SetMenuStatus(config, DISCONNECTING);
|
||||
myLoadString(INFO_STATE_WAIT_TERM);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetEvent(o.cnn[config].exit_event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StopAllOpenVPN()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < o.num_configs; i++) {
|
||||
if(o.cnn[i].connect_status != DISCONNECTED)
|
||||
StopOpenVPN(i);
|
||||
}
|
||||
|
||||
/* Wait for all connections to terminate (Max 5 sec) */
|
||||
for (i=0; i<20; i++, Sleep(250))
|
||||
if (CountConnectedState(DISCONNECTED) == o.num_configs) break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOL CALLBACK StatusDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
BOOL Translated;
|
||||
HWND hwndLogWindow;
|
||||
RECT rect;
|
||||
CHARFORMAT charformat;
|
||||
HICON hIcon;
|
||||
int config;
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
/* Set Window Icon "DisConnected" */
|
||||
SetStatusWinIcon(hwndDlg, APP_ICON_CONNECTING);
|
||||
|
||||
/* Create LogWindow */
|
||||
hwndLogWindow = CreateWindowEx (0, RICHEDIT_CLASS, NULL,
|
||||
WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | \
|
||||
ES_SUNKEN | ES_LEFT | ES_MULTILINE | \
|
||||
ES_READONLY | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
|
||||
20, 25, 350, 160, // Posision and Size
|
||||
hwndDlg, // Parent window handle
|
||||
(HMENU) EDIT_LOG, // hMenu
|
||||
o.hInstance, // hInstance
|
||||
NULL); // WM_CREATE lpParam
|
||||
|
||||
|
||||
if (!hwndLogWindow)
|
||||
{
|
||||
/* Create RichEd LogWindow Failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_RICHED_LOGWINDOW, "");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set font and fontsize of the LogWindow */
|
||||
charformat.cbSize = sizeof(CHARFORMAT);
|
||||
charformat.dwMask = CFM_SIZE | CFM_FACE | CFM_BOLD | CFM_ITALIC | \
|
||||
CFM_UNDERLINE | CFM_STRIKEOUT | CFM_PROTECTED;
|
||||
charformat.dwEffects = 0;
|
||||
charformat.yHeight = 100;
|
||||
strcpy(charformat.szFaceName, "MS Sans Serif");
|
||||
if ((SendMessage(hwndLogWindow, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &charformat) && CFM_SIZE) == 0) {
|
||||
/* set size failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_SET_SIZE, "");
|
||||
}
|
||||
|
||||
/* Set Size and Posision of controls */
|
||||
GetClientRect(hwndDlg, &rect);
|
||||
MoveWindow (hwndLogWindow, 20, 25, rect.right - 40, rect.bottom - 70, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, TEXT_STATUS), 20, 5, rect.right - 25, 15, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, ID_DISCONNECT), 20, rect.bottom - 30, 90, 23, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, ID_RESTART), 125, rect.bottom - 30, 90, 23, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, ID_HIDE), rect.right - 110, rect.bottom - 30, 90, 23, TRUE);
|
||||
|
||||
/* Set focus on the LogWindow so it scrolls automatically */
|
||||
SetFocus(hwndLogWindow);
|
||||
|
||||
return FALSE;
|
||||
|
||||
case WM_SIZE:
|
||||
MoveWindow (GetDlgItem(hwndDlg, EDIT_LOG), 20, 25, LOWORD (lParam) - 40,
|
||||
HIWORD (lParam) - 70, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, ID_DISCONNECT), 20,
|
||||
HIWORD (lParam) - 30, 90, 23, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, ID_RESTART), 125,
|
||||
HIWORD (lParam) - 30, 90, 23, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, ID_HIDE), LOWORD (lParam) - 110,
|
||||
HIWORD (lParam) - 30, 90, 23, TRUE);
|
||||
MoveWindow (GetDlgItem(hwndDlg, TEXT_STATUS), 20, 5, LOWORD (lParam) - 25, 15, TRUE);
|
||||
InvalidateRect(hwndDlg, NULL, TRUE);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
config=GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE);
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case ID_DISCONNECT:
|
||||
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
|
||||
StopOpenVPN(config);
|
||||
return TRUE;
|
||||
|
||||
case ID_HIDE:
|
||||
if (o.cnn[GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE)].connect_status != DISCONNECTED)
|
||||
{
|
||||
ShowWindow(hwndDlg, SW_HIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyWindow(hwndDlg);
|
||||
}
|
||||
return TRUE;
|
||||
case ID_RESTART:
|
||||
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
|
||||
o.cnn[config].restart = true;
|
||||
StopOpenVPN(config);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SHOWWINDOW:
|
||||
if (wParam == TRUE)
|
||||
{
|
||||
config=GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE);
|
||||
if (o.cnn[config].hwndStatus)
|
||||
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_CLOSE:
|
||||
if (o.cnn[GetDlgItemInt(hwndDlg, TEXT_CONFIG, &Translated, FALSE)].connect_status != DISCONNECTED)
|
||||
{
|
||||
ShowWindow(hwndDlg, SW_HIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestroyWindow(hwndDlg);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SetStatusWinIcon(HWND hwndDlg, int IconID)
|
||||
{
|
||||
HICON hIcon;
|
||||
|
||||
/* Set Window Icon */
|
||||
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IconID),
|
||||
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
if (hIcon) {
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
|
||||
}
|
||||
}
|
||||
|
||||
int AutoStartConnections()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if (o.cnn[i].auto_connect)
|
||||
StartOpenVPN(i);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
int VerifyAutoConnections()
|
||||
{
|
||||
int i,j;
|
||||
BOOL match;
|
||||
|
||||
for (i=0; (o.auto_connect[i] != 0) && (i < MAX_CONFIGS); i++)
|
||||
{
|
||||
match = false;
|
||||
for (j=0; j < MAX_CONFIGS; j++)
|
||||
{
|
||||
if (strcasecmp(o.cnn[j].config_file, o.auto_connect[i]) == 0)
|
||||
{
|
||||
match=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match == false)
|
||||
{
|
||||
/* autostart config not found */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_AUTOSTART_CONF_NOT_FOUND, o.auto_connect[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int CheckVersion()
|
||||
{
|
||||
HANDLE hOutputReadTmp = NULL;
|
||||
HANDLE hOutputRead = NULL;
|
||||
HANDLE hOutputWrite = NULL;
|
||||
HANDLE hInputWriteTmp = NULL;
|
||||
HANDLE hInputRead = NULL;
|
||||
HANDLE hInputWrite = NULL;
|
||||
HANDLE exit_event;
|
||||
HANDLE debug_event;
|
||||
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
char line[1024];
|
||||
char bin_path[MAX_PATH];
|
||||
char *p;
|
||||
int oldversion, i;
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
exit_event = CreateEvent (NULL, TRUE, FALSE, "openvpn_exit");
|
||||
if (exit_event == NULL)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
PrintErrorDebug("CreateEvent(openvpn_exit) failed.");
|
||||
#endif
|
||||
if (GetLastError() == ERROR_ACCESS_DENIED)
|
||||
{
|
||||
/* Assume we're running OpenVPN 1.5/1.6 and the service is started. */
|
||||
o.oldversion=1;
|
||||
strncpy(o.connect_string, "Successful ARP Flush", sizeof(o.connect_string));
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CreateEvent failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_VERSION_CREATE_EVENT, "");
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PrintErrorDebug("CreateEvent(openvpn_exit) succeded.");
|
||||
#endif
|
||||
|
||||
/* construct command line */
|
||||
mysnprintf (command_line, "openvpn --version");
|
||||
|
||||
/* construct bin path */
|
||||
strncpy(bin_path, o.exe_path, sizeof(bin_path));
|
||||
for (i=strlen(bin_path) - 1; i > 0; i--)
|
||||
if (bin_path[i] == '\\') break;
|
||||
bin_path[i] = '\0';
|
||||
|
||||
/* Make security attributes struct for logfile handle so it can
|
||||
be inherited. */
|
||||
sa.nLength = sizeof (sa);
|
||||
sa.lpSecurityDescriptor = &sd;
|
||||
sa.bInheritHandle = TRUE;
|
||||
if (!InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
|
||||
{
|
||||
/* Init Sec. Desc. failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_INIT_SEC_DESC, "");
|
||||
return(0);
|
||||
}
|
||||
if (!SetSecurityDescriptorDacl (&sd, TRUE, NULL, FALSE))
|
||||
{
|
||||
/* Set Dacl failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_SET_SEC_DESC_ACL, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Create the child input pipe. */
|
||||
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
|
||||
{
|
||||
/* create pipe failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_INPUT_READ, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Create the child output pipe. */
|
||||
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
|
||||
{
|
||||
/* CreatePipe failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PIPE_OUTPUT, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
|
||||
GetCurrentProcess(),
|
||||
&hOutputRead, // Address of new handle.
|
||||
0,FALSE, // Make it uninheritable.
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* DuplicateHandle failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_OUTPUT_READ, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
|
||||
GetCurrentProcess(),
|
||||
&hInputWrite, // Address of new handle.
|
||||
0,FALSE, // Make it uninheritable.
|
||||
DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
/* DuplicateHandle failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_DUP_HANDLE_INPUT_WRITE, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Close inheritable copies of the handles */
|
||||
if (!CloseHandle(hOutputReadTmp) || !CloseHandle(hInputWriteTmp))
|
||||
{
|
||||
/* CloseHandle failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CLOSE_HANDLE_TMP, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
|
||||
start_info.wShowWindow = SW_HIDE;
|
||||
start_info.hStdInput = hInputRead;
|
||||
start_info.hStdOutput = hOutputWrite;
|
||||
start_info.hStdError = hOutputWrite;
|
||||
|
||||
/* Start OpenVPN to check version */
|
||||
if (!CreateProcess(o.exe_path,
|
||||
command_line,
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
CREATE_NEW_CONSOLE,
|
||||
NULL,
|
||||
bin_path,
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
/* CreateProcess failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_PROCESS,
|
||||
o.exe_path,
|
||||
command_line,
|
||||
bin_path);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Default value for oldversion */
|
||||
oldversion=0;
|
||||
|
||||
/* Default string to look for to report "Connected". */
|
||||
strncpy(o.connect_string, "Successful ARP Flush", sizeof(o.connect_string));
|
||||
|
||||
if (ReadLineFromStdOut(hOutputRead, 0, line) == 1)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
PrintDebug("VersionString: %s", line);
|
||||
#endif
|
||||
if (line[8] == '2') /* Majorversion = 2 */
|
||||
{
|
||||
if (line[10] == '0') /* Minorversion = 0 */
|
||||
{
|
||||
p=strstr(line, "beta");
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p[5] == ' ') /* 2.0-beta1 - 2.0-beta9 */
|
||||
{
|
||||
if (p[4] >= '6') /* 2.0-beta6 - 2.0-beta9 */
|
||||
{
|
||||
oldversion=0;
|
||||
}
|
||||
else /* < 2.0-beta6 */
|
||||
{
|
||||
oldversion=1;
|
||||
}
|
||||
}
|
||||
else /* >= 2.0-beta10 */
|
||||
{
|
||||
if (strncmp(&p[6], "ms", 2) == 0) /* 2.0-betaXXms */
|
||||
strncpy(o.connect_string, "Initialization Sequence Completed",
|
||||
sizeof(o.connect_string));
|
||||
if ( !((p[4] == 1) && (p[5] == 0)) ) /* >= 2.0-beta11 */
|
||||
strncpy(o.connect_string, "Initialization Sequence Completed",
|
||||
sizeof(o.connect_string));
|
||||
|
||||
oldversion=0;
|
||||
}
|
||||
}
|
||||
else /* 2.0 non-beta */
|
||||
{
|
||||
strncpy(o.connect_string, "Initialization Sequence Completed",
|
||||
sizeof(o.connect_string));
|
||||
oldversion=0;
|
||||
}
|
||||
}
|
||||
else /* > 2.0 */
|
||||
{
|
||||
strncpy(o.connect_string, "Initialization Sequence Completed",
|
||||
sizeof(o.connect_string));
|
||||
oldversion=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line[8] == '1') /* Majorversion = 1 */
|
||||
{
|
||||
oldversion=1;
|
||||
}
|
||||
else /* Majorversion != (1 || 2) */
|
||||
{
|
||||
oldversion=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else return(0);
|
||||
|
||||
o.oldversion = oldversion;
|
||||
|
||||
|
||||
if(!CloseHandle (proc_info.hThread) || !CloseHandle (hOutputWrite)
|
||||
|| !CloseHandle (hInputRead) || !CloseHandle(exit_event))
|
||||
{
|
||||
/* CloseHandle failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CLOSE_HANDLE, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Return num of connections with Status = CheckVal */
|
||||
int CountConnectedState(int CheckVal)
|
||||
{
|
||||
int i;
|
||||
int count=0;
|
||||
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if (o.cnn[i].connect_status == CheckVal)
|
||||
count++;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
void CheckAndSetTrayIcon()
|
||||
{
|
||||
|
||||
/* Show green icon if service is running */
|
||||
if (o.service_running == SERVICE_CONNECTED)
|
||||
{
|
||||
SetTrayIcon(CONNECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Change tray icon if no more connections is running */
|
||||
if (CountConnectedState(CONNECTED) != 0)
|
||||
SetTrayIcon(CONNECTED);
|
||||
else
|
||||
{
|
||||
if ((CountConnectedState(CONNECTING) != 0) ||
|
||||
(CountConnectedState(RECONNECTING) != 0) ||
|
||||
(o.service_running == SERVICE_CONNECTING))
|
||||
SetTrayIcon(CONNECTING);
|
||||
else
|
||||
SetTrayIcon(DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadOpenVPNStatus(int config)
|
||||
{
|
||||
char conn_name[200];
|
||||
HANDLE hThread;
|
||||
DWORD IDThread;
|
||||
char msg[200];
|
||||
MSG messages;
|
||||
|
||||
/* Cut of extention from config filename. */
|
||||
strncpy(conn_name, o.cnn[config].config_file, sizeof(conn_name));
|
||||
conn_name[strlen(conn_name) - (strlen(o.ext_string)+1)]=0;
|
||||
|
||||
if (o.cnn[config].restart)
|
||||
{
|
||||
/* UserInfo: Connecting */
|
||||
TCHAR buf[1000];
|
||||
myLoadString(INFO_STATE_CONNECTING);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTING);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), TRUE);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), TRUE);
|
||||
SetFocus(GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG));
|
||||
o.cnn[config].restart = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create and Show Status Dialog */
|
||||
TCHAR buf[1000];
|
||||
if (!(o.cnn[config].hwndStatus = CreateDialog (o.hInstance,
|
||||
MAKEINTRESOURCE (IDD_STATUS),
|
||||
NULL, (DLGPROC) StatusDialogFunc)))
|
||||
ExitThread(1);
|
||||
/* UserInfo: Connecting */
|
||||
myLoadString(INFO_STATE_CONNECTING);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, (LPCTSTR)buf);
|
||||
SetDlgItemInt(o.cnn[config].hwndStatus, TEXT_CONFIG, (UINT)config, FALSE);
|
||||
myLoadString(INFO_CONNECTION_XXX);
|
||||
mysnprintf(msg, buf, conn_name);
|
||||
SetWindowText(o.cnn[config].hwndStatus, msg);
|
||||
|
||||
if (o.silent_connection[0]=='0')
|
||||
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
|
||||
}
|
||||
|
||||
|
||||
/* Start Thread to monitor our OpenVPN process */
|
||||
hThread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) WatchOpenVPNProcess,
|
||||
(int *) config, // pass config nr
|
||||
0, &IDThread);
|
||||
if (hThread == NULL)
|
||||
{
|
||||
/* CreateThread failed */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_THREAD_READ_STDOUT, "");
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
/* Run the message loop. It will run until GetMessage() returns 0 */
|
||||
while (GetMessage (&messages, NULL, 0, 0))
|
||||
{
|
||||
if(!IsDialogMessage(o.cnn[config].hwndStatus, &messages))
|
||||
{
|
||||
TranslateMessage(&messages);
|
||||
DispatchMessage(&messages);
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
struct process_info {
|
||||
HANDLE hProcess;
|
||||
int config;
|
||||
};
|
||||
|
||||
int StartOpenVPN(int config);
|
||||
void StopOpenVPN(int config);
|
||||
void SuspendOpenVPN(int config);
|
||||
void StopAllOpenVPN();
|
||||
int ReadLineFromStdOut(HANDLE hStdOut, int config, char line[1024]);
|
||||
BOOL CALLBACK StatusDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
int AutoStartConnections();
|
||||
int VerifyAutoConnections();
|
||||
int CheckVersion();
|
||||
int CountConnectedState(int CheckVal);
|
||||
void CheckAndSetTrayIcon();
|
||||
void SetStatusWinIcon(HWND hwndDlg, int IconID);
|
||||
void ThreadOpenVPNStatus(int status) __attribute__ ((noreturn));
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include "main.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
#include "options.h"
|
||||
|
||||
#define MATCH_FALSE 0
|
||||
#define MATCH_FILE 1
|
||||
#define MATCH_DIR 2
|
||||
|
||||
extern struct options o;
|
||||
|
||||
static int
|
||||
match (const WIN32_FIND_DATA *find, const char *ext)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
return MATCH_DIR;
|
||||
|
||||
if (!strlen (ext))
|
||||
return MATCH_FILE;
|
||||
|
||||
i = strlen (find->cFileName) - strlen (ext) - 1;
|
||||
if (i < 1)
|
||||
return MATCH_FALSE;
|
||||
|
||||
if (find->cFileName[i] == '.' && !strcasecmp (find->cFileName + i + 1, ext))
|
||||
return MATCH_FILE;
|
||||
else
|
||||
return MATCH_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify the extension on a filename.
|
||||
*/
|
||||
static bool
|
||||
modext (char *dest, unsigned int size, const char *src, const char *newext)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (size > 0 && (strlen (src) + 1) <= size)
|
||||
{
|
||||
strcpy (dest, src);
|
||||
dest [size - 1] = '\0';
|
||||
i = strlen (dest);
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (dest[i] == '\\')
|
||||
break;
|
||||
if (dest[i] == '.')
|
||||
{
|
||||
dest[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (strlen (dest) + strlen(newext) + 2 <= size)
|
||||
{
|
||||
strcat (dest, ".");
|
||||
strcat (dest, newext);
|
||||
return true;
|
||||
}
|
||||
dest [0] = '\0';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ConfigAlreadyExists(char newconfig[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<o.num_configs; i++)
|
||||
{
|
||||
if (strcasecmp(o.cnn[i].config_file, newconfig) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int AddConfigFileToList(int config, char filename[], char config_dir[])
|
||||
{
|
||||
char log_file[MAX_PATH];
|
||||
int i;
|
||||
|
||||
/* Save config file name */
|
||||
strncpy(o.cnn[config].config_file, filename, sizeof(o.cnn[config].config_file));
|
||||
|
||||
/* Save config dir */
|
||||
strncpy(o.cnn[config].config_dir, config_dir, sizeof(o.cnn[config].config_dir));
|
||||
|
||||
/* Save connection name (config_name - extension) */
|
||||
strncpy(o.cnn[config].config_name, o.cnn[config].config_file,
|
||||
sizeof(o.cnn[config].config_name));
|
||||
o.cnn[config].config_name[strlen(o.cnn[config].config_name) -
|
||||
(strlen(o.ext_string)+1)]=0;
|
||||
|
||||
/* get log file pathname */
|
||||
if (!modext (log_file, sizeof (log_file), o.cnn[config].config_file, "log"))
|
||||
{
|
||||
/* cannot construct logfile-name */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CANNOT_CONSTRUCT_LOG, o.cnn[config].config_file);
|
||||
return(false);
|
||||
}
|
||||
mysnprintf (o.cnn[config].log_path, "%s\\%s", o.log_dir, log_file);
|
||||
|
||||
/* Check if connection should be autostarted */
|
||||
for (i=0; (i < MAX_CONFIGS) && o.auto_connect[i]; i++)
|
||||
{
|
||||
if (strcasecmp(o.cnn[config].config_file, o.auto_connect[i]) == 0)
|
||||
{
|
||||
o.cnn[config].auto_connect = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BuildFileList()
|
||||
{
|
||||
WIN32_FIND_DATA find_obj;
|
||||
HANDLE find_handle;
|
||||
BOOL more_files;
|
||||
char find_string[MAX_PATH];
|
||||
int i;
|
||||
char subdir_table[MAX_CONFIG_SUBDIRS][MAX_PATH];
|
||||
int subdir=0;
|
||||
int subdir_counter=0;
|
||||
|
||||
/* Reset config counter */
|
||||
o.num_configs=0;
|
||||
|
||||
mysnprintf (find_string, "%s\\*", o.config_dir);
|
||||
|
||||
find_handle = FindFirstFile (find_string, &find_obj);
|
||||
if (find_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop over each config file in main config dir
|
||||
*/
|
||||
do
|
||||
{
|
||||
if (o.num_configs >= MAX_CONFIGS)
|
||||
{
|
||||
/* too many configs */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_TO_MANY_CONFIGS, MAX_CONFIGS);
|
||||
break;
|
||||
}
|
||||
|
||||
/* does file have the correct type and extension? */
|
||||
if (match (&find_obj, o.ext_string) == MATCH_FILE)
|
||||
{
|
||||
/* Add config file to list */
|
||||
AddConfigFileToList(o.num_configs, find_obj.cFileName, o.config_dir);
|
||||
|
||||
o.num_configs++;
|
||||
}
|
||||
|
||||
if (match (&find_obj, o.ext_string) == MATCH_DIR)
|
||||
{
|
||||
if ((strncmp(find_obj.cFileName, ".", strlen(find_obj.cFileName)) != 0) &&
|
||||
(strncmp(find_obj.cFileName, "..", strlen(find_obj.cFileName)) != 0) &&
|
||||
(subdir < MAX_CONFIG_SUBDIRS))
|
||||
{
|
||||
/* Add dir to dir_table */
|
||||
mysnprintf(subdir_table[subdir], "%s\\%s", o.config_dir, find_obj.cFileName);
|
||||
subdir++;
|
||||
}
|
||||
}
|
||||
|
||||
/* more files to process? */
|
||||
more_files = FindNextFile (find_handle, &find_obj);
|
||||
} while (more_files);
|
||||
|
||||
FindClose (find_handle);
|
||||
|
||||
|
||||
/*
|
||||
* Loop over each config file in every subdir
|
||||
*/
|
||||
for (subdir_counter=0; subdir_counter < subdir; subdir_counter++)
|
||||
{
|
||||
|
||||
mysnprintf (find_string, "%s\\*", subdir_table[subdir_counter]);
|
||||
|
||||
find_handle = FindFirstFile (find_string, &find_obj);
|
||||
if (find_handle == INVALID_HANDLE_VALUE)
|
||||
continue;
|
||||
|
||||
do
|
||||
{
|
||||
if (o.num_configs >= MAX_CONFIGS)
|
||||
{
|
||||
/* too many configs */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_TO_MANY_CONFIGS, MAX_CONFIGS);
|
||||
FindClose (find_handle);
|
||||
return(true);
|
||||
}
|
||||
|
||||
/* does file have the correct type and extension? */
|
||||
if (match (&find_obj, o.ext_string) == MATCH_FILE)
|
||||
{
|
||||
if (!ConfigAlreadyExists(find_obj.cFileName))
|
||||
{
|
||||
/* Add config file to list */
|
||||
AddConfigFileToList(o.num_configs, find_obj.cFileName, subdir_table[subdir_counter]);
|
||||
o.num_configs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Config filename already exists */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CONFIG_ALREADY_EXIST, find_obj.cFileName);
|
||||
}
|
||||
}
|
||||
|
||||
/* more files to process? */
|
||||
more_files = FindNextFile (find_handle, &find_obj);
|
||||
} while (more_files);
|
||||
|
||||
FindClose (find_handle);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
int BuildFileList();
|
|
@ -0,0 +1,649 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*
|
||||
* Parts of this sourcefile is taken from openvpnserv.c from the
|
||||
* OpenVPN source, with approval from the author, James Yonan
|
||||
* <jim@yonan.net>.
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "openvpn.h"
|
||||
#include "scripts.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
#include "passphrase.h"
|
||||
#include "tray.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
/* Wait for a complete line (CR/LF) and return it.
|
||||
* Return values:
|
||||
* 1 - Successful. Line is available in *line.
|
||||
* 0 - Broken Pipe during ReadFile.
|
||||
* -1 - Other Error during ReadFile.
|
||||
*
|
||||
* I'm really unhappy with this code! If anyone knows of an easier
|
||||
* way to convert the streaming data from ReadFile() into lines,
|
||||
* please let me know!
|
||||
*/
|
||||
int ReadLineFromStdOut(HANDLE hStdOut, int config, char *line)
|
||||
{
|
||||
#define MAX_LINELEN 1024
|
||||
|
||||
CHAR lpBuffer[MAX_LINELEN];
|
||||
static char lastline[MAX_CONFIGS][MAX_LINELEN];
|
||||
static int charsleft[MAX_CONFIGS];
|
||||
char tmpline[MAX_LINELEN];
|
||||
DWORD nBytesRead;
|
||||
DWORD nCharsWritten;
|
||||
char *p;
|
||||
unsigned int len, i;
|
||||
static int first_call = 1;
|
||||
extern HINSTANCE hInstance;
|
||||
|
||||
if (first_call)
|
||||
{
|
||||
for (i=0; i < MAX_CONFIGS; i++)
|
||||
charsleft[i]=0;
|
||||
first_call = 0;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (charsleft[config])
|
||||
{
|
||||
/* Check for Passphrase prompt */
|
||||
CheckPrivateKeyPassphrasePrompt(lastline[config], config);
|
||||
|
||||
/* Check for Username/Password Auth prompt */
|
||||
CheckAuthUsernamePrompt(lastline[config], config);
|
||||
CheckAuthPasswordPrompt(lastline[config]);
|
||||
|
||||
p=strchr(lastline[config], '\n');
|
||||
if (p == NULL)
|
||||
{
|
||||
if (!ReadFile(hStdOut,lpBuffer,sizeof(lpBuffer) - strlen(lastline[config]) - 1,
|
||||
&nBytesRead,NULL) || !nBytesRead)
|
||||
{
|
||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
||||
return(0); // pipe done - normal exit path.
|
||||
else
|
||||
{
|
||||
/* error reading from pipe */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_READ_STDOUT_PIPE, "");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
lpBuffer[nBytesRead] = '\0';
|
||||
p=strchr(lpBuffer, '\n');
|
||||
if (p == NULL)
|
||||
{
|
||||
strncat(lastline[config], lpBuffer, sizeof(lastline[config]) - strlen(lastline[config]) - 1);
|
||||
if (strlen(lastline[config]) >= (MAX_LINELEN - 1))
|
||||
{
|
||||
strncpy(line, lastline[config], MAX_LINELEN);
|
||||
charsleft[config]=0;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = '\0';
|
||||
strncpy(line, lastline[config], MAX_LINELEN - 1);
|
||||
strncat(line, lpBuffer, MAX_LINELEN - strlen(line));
|
||||
if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0';
|
||||
if (nBytesRead > (strlen(lpBuffer) + 1))
|
||||
{
|
||||
strncpy(lastline[config], p+1, sizeof(lastline[config]) - 1);
|
||||
charsleft[config]=1;
|
||||
return(1);
|
||||
}
|
||||
charsleft[config]=0;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len = strlen(lastline[config]);
|
||||
p[0] = '\0';
|
||||
strncpy(line, lastline[config], MAX_LINELEN - 1);
|
||||
if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0';
|
||||
if (len > (strlen(line) + 2))
|
||||
{
|
||||
strncpy(tmpline, p+1, sizeof(tmpline) - 1);
|
||||
strncpy(lastline[config], tmpline, sizeof(lastline[config]) - 1);
|
||||
charsleft[config]=1;
|
||||
return(1);
|
||||
}
|
||||
charsleft[config]=0;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadFile(hStdOut,lpBuffer,sizeof(lpBuffer) - 1,
|
||||
&nBytesRead,NULL) || !nBytesRead)
|
||||
{
|
||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
||||
return(0); // pipe done - normal exit path.
|
||||
else
|
||||
{
|
||||
/* error reading from pipe */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_READ_STDOUT_PIPE, "");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
lpBuffer[nBytesRead] = '\0';
|
||||
p=strchr(lpBuffer, '\n');
|
||||
if (p == NULL)
|
||||
{
|
||||
if (nBytesRead >= (MAX_LINELEN - 1))
|
||||
{
|
||||
strncpy(line, lpBuffer, MAX_LINELEN);
|
||||
charsleft[config]=0;
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(lastline[config], lpBuffer, sizeof(lastline[config]) - 1);
|
||||
charsleft[config]=1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = '\0';
|
||||
strncpy(line, lpBuffer, MAX_LINELEN - 1);
|
||||
if (line[strlen(line) - 1] == '\r') line[strlen(line) - 1] = '\0';
|
||||
if (nBytesRead > strlen(line))
|
||||
{
|
||||
strncpy(lastline[config], p+1, sizeof(lastline[config]) - 1);
|
||||
charsleft[config]=1;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Monitor the openvpn log output while CONNECTING
|
||||
*/
|
||||
void monitor_openvpnlog_while_connecting(int config, char *line)
|
||||
{
|
||||
TCHAR buf[1000];
|
||||
char msg[200];
|
||||
char msg2[200];
|
||||
unsigned int i;
|
||||
char *linepos;
|
||||
|
||||
/* Check for Connected message */
|
||||
if (strstr(line, o.connect_string) != NULL)
|
||||
{
|
||||
/* Run Connect Script */
|
||||
RunConnectScript(config, false);
|
||||
|
||||
/* Save time when we got connected. */
|
||||
o.cnn[config].connected_since = time(NULL);
|
||||
|
||||
o.cnn[config].connect_status = CONNECTED;
|
||||
SetMenuStatus(config, CONNECTED);
|
||||
SetTrayIcon(CONNECTED);
|
||||
|
||||
/* Remove Proxy Auth file */
|
||||
DeleteFile(o.proxy_authfile);
|
||||
|
||||
/* Zero psw attempt counter */
|
||||
o.cnn[config].failed_psw_attempts = 0;
|
||||
|
||||
/* UserInfo: Connected */
|
||||
myLoadString(INFO_STATE_CONNECTED);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTED);
|
||||
|
||||
/* Show Tray Balloon msg */
|
||||
if (o.show_balloon[0] != '0')
|
||||
{
|
||||
myLoadString(INFO_NOW_CONNECTED);
|
||||
mysnprintf(msg, buf, o.cnn[config].config_name);
|
||||
if (strlen(o.cnn[config].ip) > 0)
|
||||
{
|
||||
myLoadString(INFO_ASSIG_IP);
|
||||
mysnprintf(msg2, buf, o.cnn[config].ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf(msg2," ");
|
||||
}
|
||||
ShowTrayBalloon(msg, msg2);
|
||||
}
|
||||
|
||||
/* Hide Status Window */
|
||||
ShowWindow(o.cnn[config].hwndStatus, SW_HIDE);
|
||||
}
|
||||
|
||||
/* Check for failed passphrase log message */
|
||||
if ((strstr(line, "TLS Error: Need PEM pass phrase for private key") != NULL) ||
|
||||
(strstr(line, "EVP_DecryptFinal:bad decrypt") != NULL) ||
|
||||
(strstr(line, "PKCS12_parse:mac verify failure") != NULL) ||
|
||||
(strstr(line, "Received AUTH_FAILED control message") != NULL) ||
|
||||
(strstr(line, "Auth username is empty") != NULL))
|
||||
{
|
||||
o.cnn[config].failed_psw_attempts++;
|
||||
o.cnn[config].failed_psw=1;
|
||||
o.cnn[config].restart=true;
|
||||
}
|
||||
|
||||
/* Check for "certificate has expired" message */
|
||||
if ((strstr(line, "error=certificate has expired") != NULL))
|
||||
{
|
||||
StopOpenVPN(config);
|
||||
/* Cert expired... */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CERT_EXPIRED, "");
|
||||
}
|
||||
|
||||
/* Check for "certificate is not yet valid" message */
|
||||
if ((strstr(line, "error=certificate is not yet valid") != NULL))
|
||||
{
|
||||
StopOpenVPN(config);
|
||||
/* Cert not yet valid */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CERT_NOT_YET_VALID, "");
|
||||
}
|
||||
|
||||
/* Check for "Notified TAP-Win32 driver to set a DHCP IP" message */
|
||||
if (((linepos=strstr(line, "Notified TAP-Win32 driver to set a DHCP IP")) != NULL))
|
||||
{
|
||||
strncpy(o.cnn[config].ip, linepos+54, 15); /* Copy IP address */
|
||||
for (i=0; i < strlen(o.cnn[config].ip); i++)
|
||||
if (o.cnn[config].ip[i] == '/' || o.cnn[config].ip[i] == ' ') break;
|
||||
o.cnn[config].ip[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Monitor the openvpn log output while CONNECTED
|
||||
*/
|
||||
void monitor_openvpnlog_while_connected(int config, char *line)
|
||||
{
|
||||
TCHAR buf[1000];
|
||||
|
||||
/* Check for Ping-Restart message */
|
||||
if (strstr(line, "process restarting") != NULL)
|
||||
{
|
||||
/* Set connect_status = ReConnecting */
|
||||
o.cnn[config].connect_status = RECONNECTING;
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
/* Set Status Window Controls "ReConnecting" */
|
||||
myLoadString(INFO_STATE_RECONNECTING);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTING);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Monitor the openvpn log output while RECONNECTING
|
||||
*/
|
||||
void monitor_openvpnlog_while_reconnecting(int config, char *line)
|
||||
{
|
||||
TCHAR buf[1000];
|
||||
char msg[200];
|
||||
char msg2[200];
|
||||
unsigned int i;
|
||||
char *linepos;
|
||||
|
||||
/* Check for Connected message */
|
||||
if (strstr(line, o.connect_string) != NULL)
|
||||
{
|
||||
o.cnn[config].connect_status = CONNECTED;
|
||||
SetTrayIcon(CONNECTED);
|
||||
|
||||
/* Set Status Window Controls "Connected" */
|
||||
myLoadString(INFO_STATE_CONNECTED);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_CONNECTED);
|
||||
|
||||
/* Show Tray Balloon msg */
|
||||
if (o.show_balloon[0] == '2')
|
||||
{
|
||||
myLoadString(INFO_NOW_CONNECTED);
|
||||
mysnprintf(msg, buf, o.cnn[config].config_name);
|
||||
if (strlen(o.cnn[config].ip) > 0)
|
||||
{
|
||||
myLoadString(INFO_ASSIG_IP);
|
||||
mysnprintf(msg2, buf, o.cnn[config].ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf(msg2," ");
|
||||
}
|
||||
ShowTrayBalloon(msg, msg2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for failed passphrase log message */
|
||||
if ((strstr(line, "TLS Error: Need PEM pass phrase for private key") != NULL) ||
|
||||
(strstr(line, "EVP_DecryptFinal:bad decrypt") != NULL) ||
|
||||
(strstr(line, "PKCS12_parse:mac verify failure") != NULL) ||
|
||||
(strstr(line, "Received AUTH_FAILED control message") != NULL) ||
|
||||
(strstr(line, "Auth username is empty") != NULL))
|
||||
{
|
||||
o.cnn[config].failed_psw_attempts++;
|
||||
o.cnn[config].failed_psw=1;
|
||||
o.cnn[config].restart=true;
|
||||
}
|
||||
|
||||
/* Check for "certificate has expired" message */
|
||||
if ((strstr(line, "error=certificate has expired") != NULL))
|
||||
{
|
||||
/* Cert expired */
|
||||
StopOpenVPN(config);
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CERT_EXPIRED, "");
|
||||
}
|
||||
|
||||
/* Check for "certificate is not yet valid" message */
|
||||
if ((strstr(line, "error=certificate is not yet valid") != NULL))
|
||||
{
|
||||
StopOpenVPN(config);
|
||||
/* Cert not yet valid */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CERT_NOT_YET_VALID, "");
|
||||
}
|
||||
|
||||
/* Check for "Notified TAP-Win32 driver to set a DHCP IP" message */
|
||||
if (((linepos=strstr(line, "Notified TAP-Win32 driver to set a DHCP IP")) != NULL))
|
||||
{
|
||||
strncpy(o.cnn[config].ip, linepos+54, 15); /* Copy IP address */
|
||||
for (i=0; i < strlen(o.cnn[config].ip); i++)
|
||||
if (o.cnn[config].ip[i] == '/' || o.cnn[config].ip[i] == ' ') break;
|
||||
o.cnn[config].ip[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Opens a log file and monitors the started OpenVPN process.
|
||||
* All output from OpenVPN is written both to the logfile and
|
||||
* to the status window.
|
||||
*
|
||||
* The output from OpenVPN is also watch for diffrent messages
|
||||
* and appropriate actions are taken.
|
||||
*/
|
||||
void WatchOpenVPNProcess(int config)
|
||||
{
|
||||
char line[1024];
|
||||
int ret;
|
||||
char filemode[2] = "w\0";
|
||||
FILE *fd;
|
||||
char msg[200];
|
||||
char msg2[200];
|
||||
int i;
|
||||
int iLineCount;
|
||||
int LogLines = 0;
|
||||
int logpos;
|
||||
char *linepos;
|
||||
HWND LogWindow;
|
||||
TCHAR buf[1000];
|
||||
|
||||
/* set log file append/truncate filemode */
|
||||
if (o.append_string[0] == '1')
|
||||
filemode[0] = 'a';
|
||||
|
||||
/* Set Connect_Status = "Connecting" */
|
||||
o.cnn[config].connect_status = CONNECTING;
|
||||
|
||||
/* Set Tray Icon = "Connecting" if no other connections are running */
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
/* Set MenuStatus = "Connecting" */
|
||||
SetMenuStatus(config, CONNECTING);
|
||||
|
||||
/* Clear failed_password flag */
|
||||
o.cnn[config].failed_psw = 0;
|
||||
|
||||
/* Open log file */
|
||||
if ((fd=fopen(o.cnn[config].log_path, filemode)) == NULL)
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_OPEN_LOG_WRITE, o.cnn[config].log_path);
|
||||
|
||||
LogWindow = GetDlgItem(o.cnn[config].hwndStatus, EDIT_LOG);
|
||||
while(TRUE)
|
||||
{
|
||||
if ((ret=ReadLineFromStdOut(o.cnn[config].hStdOut, config, line)) == 1)
|
||||
{
|
||||
|
||||
/* Do nothing if line length = 0 */
|
||||
if (strlen(line) == 0) continue;
|
||||
|
||||
/* Write line to Log file */
|
||||
if (fd != NULL)
|
||||
{
|
||||
fputs (line, fd);
|
||||
fputc ('\n', fd);
|
||||
fflush (fd);
|
||||
}
|
||||
|
||||
/* Remove lines from LogWindow if it is getting full */
|
||||
LogLines++;
|
||||
if (LogLines > MAX_LOG_LINES)
|
||||
{
|
||||
logpos = SendMessage(LogWindow, EM_LINEINDEX, DEL_LOG_LINES, 0);
|
||||
SendMessage(LogWindow, EM_SETSEL, 0, logpos);
|
||||
SendMessage(LogWindow, EM_REPLACESEL, FALSE, (LPARAM) "");
|
||||
LogLines -= DEL_LOG_LINES;
|
||||
}
|
||||
|
||||
/* Write line to LogWindow */
|
||||
strcat(line, "\r\n");
|
||||
SendMessage(LogWindow, EM_SETSEL, (WPARAM) -1, (LPARAM) -1);
|
||||
SendMessage(LogWindow, EM_REPLACESEL, FALSE, (LPARAM) line);
|
||||
|
||||
if (o.cnn[config].connect_status == CONNECTING) /* Connecting state */
|
||||
monitor_openvpnlog_while_connecting(config, line);
|
||||
|
||||
if (o.cnn[config].connect_status == CONNECTED) /* Connected state */
|
||||
monitor_openvpnlog_while_connected(config, line);
|
||||
|
||||
if (o.cnn[config].connect_status == RECONNECTING) /* ReConnecting state */
|
||||
monitor_openvpnlog_while_reconnecting(config, line);
|
||||
}
|
||||
else break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* OpenVPN has been shutdown */
|
||||
|
||||
/* Close logfile filedesc. */
|
||||
if (fd != NULL) fclose(fd);
|
||||
|
||||
/* Close StdIn/StdOut handles */
|
||||
CloseHandle(o.cnn[config].hStdIn);
|
||||
CloseHandle(o.cnn[config].hStdOut);
|
||||
|
||||
/* Close exitevent handle */
|
||||
CloseHandle(o.cnn[config].exit_event);
|
||||
o.cnn[config].exit_event = NULL;
|
||||
|
||||
/* Enable/Disable menuitems for this connections */
|
||||
SetMenuStatus(config, DISCONNECTING);
|
||||
|
||||
/* Remove Proxy Auth file */
|
||||
DeleteFile(o.proxy_authfile);
|
||||
|
||||
/* Process died outside our control */
|
||||
if(o.cnn[config].connect_status == CONNECTED)
|
||||
{
|
||||
/* Zero psw attempt counter */
|
||||
o.cnn[config].failed_psw_attempts = 0;
|
||||
|
||||
/* Set connect_status = "Not Connected" */
|
||||
o.cnn[config].connect_status=DISCONNECTED;
|
||||
|
||||
/* Change tray icon if no more connections is running */
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
/* Show Status Window */
|
||||
myLoadString(INFO_STATE_DISCONNECTED);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_DISCONNECTED);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
|
||||
SetForegroundWindow(o.cnn[config].hwndStatus);
|
||||
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
|
||||
ShowLocalizedMsg(GUI_NAME, INFO_CONN_TERMINATED, o.cnn[config].config_name);
|
||||
|
||||
/* Close Status Window */
|
||||
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
/* We have failed to connect */
|
||||
else if(o.cnn[config].connect_status == CONNECTING)
|
||||
{
|
||||
|
||||
/* Set connect_status = "DisConnecting" */
|
||||
o.cnn[config].connect_status=DISCONNECTING;
|
||||
|
||||
/* Change tray icon if no more connections is running */
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
if ((o.cnn[config].failed_psw) &&
|
||||
(o.cnn[config].failed_psw_attempts < o.psw_attempts))
|
||||
{
|
||||
/* Restart OpenVPN to make another attempt to connect */
|
||||
PostMessage(o.hWnd, WM_COMMAND, (WPARAM) IDM_CONNECTMENU + config, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Show Status Window */
|
||||
myLoadString(INFO_STATE_FAILED);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_DISCONNECTED);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
|
||||
SetForegroundWindow(o.cnn[config].hwndStatus);
|
||||
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
|
||||
|
||||
/* Zero psw attempt counter */
|
||||
o.cnn[config].failed_psw_attempts = 0;
|
||||
|
||||
ShowLocalizedMsg(GUI_NAME, INFO_CONN_FAILED, o.cnn[config].config_name);
|
||||
|
||||
/* Set connect_status = "Not Connected" */
|
||||
o.cnn[config].connect_status=DISCONNECTED;
|
||||
|
||||
/* Close Status Window */
|
||||
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
|
||||
|
||||
/* Reset restart flag */
|
||||
o.cnn[config].restart=false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* We have failed to reconnect */
|
||||
else if(o.cnn[config].connect_status == RECONNECTING)
|
||||
{
|
||||
|
||||
/* Set connect_status = "DisConnecting" */
|
||||
o.cnn[config].connect_status=DISCONNECTING;
|
||||
|
||||
/* Change tray icon if no more connections is running */
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
if ((o.cnn[config].failed_psw) &&
|
||||
(o.cnn[config].failed_psw_attempts < o.psw_attempts))
|
||||
{
|
||||
/* Restart OpenVPN to make another attempt to connect */
|
||||
PostMessage(o.hWnd, WM_COMMAND, (WPARAM) IDM_CONNECTMENU + config, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Show Status Window */
|
||||
myLoadString(INFO_STATE_FAILED_RECONN);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
SetStatusWinIcon(o.cnn[config].hwndStatus, APP_ICON_DISCONNECTED);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_DISCONNECT), FALSE);
|
||||
EnableWindow(GetDlgItem(o.cnn[config].hwndStatus, ID_RESTART), FALSE);
|
||||
SetForegroundWindow(o.cnn[config].hwndStatus);
|
||||
ShowWindow(o.cnn[config].hwndStatus, SW_SHOW);
|
||||
|
||||
/* Zero psw attempt counter */
|
||||
o.cnn[config].failed_psw_attempts = 0;
|
||||
|
||||
ShowLocalizedMsg(GUI_NAME, INFO_RECONN_FAILED, o.cnn[config].config_name);
|
||||
|
||||
/* Set connect_status = "Not Connected" */
|
||||
o.cnn[config].connect_status=DISCONNECTED;
|
||||
|
||||
/* Close Status Window */
|
||||
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
|
||||
|
||||
/* Reset restart flag */
|
||||
o.cnn[config].restart=false;
|
||||
}
|
||||
}
|
||||
|
||||
/* We have chosed to Disconnect */
|
||||
else if(o.cnn[config].connect_status == DISCONNECTING)
|
||||
{
|
||||
/* Zero psw attempt counter */
|
||||
o.cnn[config].failed_psw_attempts = 0;
|
||||
|
||||
/* Set connect_status = "Not Connected" */
|
||||
o.cnn[config].connect_status=DISCONNECTED;
|
||||
|
||||
/* Change tray icon if no more connections is running */
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
if (o.cnn[config].restart)
|
||||
{
|
||||
/* Restart OpenVPN */
|
||||
StartOpenVPN(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Close Status Window */
|
||||
SendMessage(o.cnn[config].hwndStatus, WM_CLOSE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* We have chosed to Suspend */
|
||||
else if(o.cnn[config].connect_status == SUSPENDING)
|
||||
{
|
||||
/* Zero psw attempt counter */
|
||||
o.cnn[config].failed_psw_attempts = 0;
|
||||
|
||||
/* Set connect_status = "SUSPENDED" */
|
||||
o.cnn[config].connect_status=SUSPENDED;
|
||||
myLoadString(INFO_STATE_SUSPENDED);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
|
||||
/* Change tray icon if no more connections is running */
|
||||
CheckAndSetTrayIcon();
|
||||
}
|
||||
|
||||
/* Enable/Disable menuitems for this connections */
|
||||
SetMenuStatus(config, DISCONNECTED);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
void WatchOpenVPNProcess(int config);
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 "options.h"
|
||||
#include "main.h"
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#include <windows.h>
|
||||
#include "openvpn-gui-res.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
void
|
||||
init_options (struct options *opt)
|
||||
{
|
||||
CLEAR (*opt);
|
||||
}
|
||||
|
||||
int Createargcargv(struct options* options, char* command_line)
|
||||
{
|
||||
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
char* arg;
|
||||
int myindex;
|
||||
int result;
|
||||
|
||||
int i;
|
||||
// count the arguments
|
||||
|
||||
argc = 1;
|
||||
arg = command_line;
|
||||
|
||||
while (arg[0] != 0) {
|
||||
|
||||
while (arg[0] != 0 && arg[0] == ' ') {
|
||||
arg++;
|
||||
}
|
||||
|
||||
if (arg[0] != 0) {
|
||||
|
||||
argc++;
|
||||
|
||||
if (arg[0] == '\"') {
|
||||
arg++;
|
||||
while (arg[0] != 0 && arg[0] != '\"') {
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
while (arg[0] != 0 && arg[0] != ' ') {
|
||||
arg++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tokenize the arguments
|
||||
argv = (char**)malloc(argc * sizeof(char*));
|
||||
|
||||
arg = command_line;
|
||||
myindex = 1;
|
||||
|
||||
while (arg[0] != 0) {
|
||||
|
||||
while (arg[0] != 0 && arg[0] == ' ') {
|
||||
arg++;
|
||||
}
|
||||
|
||||
if (arg[0] != 0) {
|
||||
|
||||
if (arg[0] == '\"') {
|
||||
arg++;
|
||||
argv[myindex] = arg;
|
||||
myindex++;
|
||||
while (arg[0] != 0 && arg[0] != '\"') {
|
||||
arg++;
|
||||
}
|
||||
if (arg[0] != 0) {
|
||||
arg[0] = 0;
|
||||
arg++;
|
||||
}
|
||||
while (arg[0] != 0 && arg[0] != ' ') {
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
argv[myindex] = arg;
|
||||
myindex++;
|
||||
while (arg[0] != 0 && arg[0] != ' ') {
|
||||
arg++;
|
||||
}
|
||||
if (arg[0] != 0) {
|
||||
arg[0] = 0;
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// put the program name into argv[0]
|
||||
char filename[_MAX_PATH];
|
||||
|
||||
GetModuleFileName(NULL, filename, _MAX_PATH);
|
||||
argv[0] = filename;
|
||||
|
||||
parse_argv(options, argc, argv);
|
||||
|
||||
free(argv);
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
parse_argv (struct options* options,
|
||||
int argc,
|
||||
char *argv[])
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* parse command line */
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
char *p[MAX_PARMS];
|
||||
CLEAR (p);
|
||||
p[0] = argv[i];
|
||||
if (strncmp(p[0], "--", 2))
|
||||
{
|
||||
/* Missing -- before option. */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_BAD_PARAMETER, p[0]);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
p[0] += 2;
|
||||
|
||||
for (j = 1; j < MAX_PARMS; ++j)
|
||||
{
|
||||
if (i + j < argc)
|
||||
{
|
||||
char *arg = argv[i + j];
|
||||
if (strncmp (arg, "--", 2))
|
||||
p[j] = arg;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = add_option (options, i, p);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
add_option (struct options *options,
|
||||
int i,
|
||||
char *p[])
|
||||
{
|
||||
|
||||
if (streq (p[0], "help"))
|
||||
{
|
||||
TCHAR usagetext[5000];
|
||||
TCHAR usagecaption[200];
|
||||
|
||||
LoadString(o.hInstance, INFO_USAGE, usagetext, sizeof(usagetext) / sizeof(TCHAR));
|
||||
LoadString(o.hInstance, INFO_USAGECAPTION, usagecaption, sizeof(usagetext) / sizeof(TCHAR));
|
||||
MessageBox(NULL, usagetext, usagecaption, MB_OK);
|
||||
exit(0);
|
||||
}
|
||||
else if (streq (p[0], "connect") && p[1])
|
||||
{
|
||||
++i;
|
||||
static int auto_connect_nr=0;
|
||||
if (auto_connect_nr == MAX_CONFIGS)
|
||||
{
|
||||
/* Too many configs */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_TO_MANY_CONFIGS, MAX_CONFIGS);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
options->auto_connect[auto_connect_nr] = p[1];
|
||||
auto_connect_nr++;
|
||||
}
|
||||
else if (streq (p[0], "exe_path") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->exe_path, p[1], sizeof(options->exe_path) - 1);
|
||||
}
|
||||
else if (streq (p[0], "config_dir") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->config_dir, p[1], sizeof(options->config_dir) - 1);
|
||||
}
|
||||
else if (streq (p[0], "ext_string") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->ext_string, p[1], sizeof(options->ext_string) - 1);
|
||||
}
|
||||
else if (streq (p[0], "log_dir") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->log_dir, p[1], sizeof(options->log_dir) - 1);
|
||||
}
|
||||
else if (streq (p[0], "priority_string") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->priority_string, p[1], sizeof(options->priority_string) - 1);
|
||||
}
|
||||
else if (streq (p[0], "append_string") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->append_string, p[1], sizeof(options->append_string) - 1);
|
||||
}
|
||||
else if (streq (p[0], "log_viewer") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->log_viewer, p[1], sizeof(options->log_viewer) - 1);
|
||||
}
|
||||
else if (streq (p[0], "editor") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->editor, p[1], sizeof(options->editor) - 1);
|
||||
}
|
||||
else if (streq (p[0], "allow_edit") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->allow_edit, p[1], sizeof(options->allow_edit) - 1);
|
||||
}
|
||||
else if (streq (p[0], "allow_service") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->allow_service, p[1], sizeof(options->allow_service) - 1);
|
||||
}
|
||||
else if (streq (p[0], "allow_password") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->allow_password, p[1], sizeof(options->allow_password) - 1);
|
||||
}
|
||||
else if (streq (p[0], "allow_proxy") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->allow_proxy, p[1], sizeof(options->allow_proxy) - 1);
|
||||
}
|
||||
else if (streq (p[0], "show_balloon") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->show_balloon, p[1], sizeof(options->show_balloon) - 1);
|
||||
}
|
||||
else if (streq (p[0], "service_only") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->service_only, p[1], sizeof(options->service_only) - 1);
|
||||
}
|
||||
else if (streq (p[0], "show_script_window") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->show_script_window, p[1], sizeof(options->show_script_window) - 1);
|
||||
}
|
||||
else if (streq (p[0], "silent_connection") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->silent_connection, p[1], sizeof(options->silent_connection) - 1);
|
||||
}
|
||||
else if (streq (p[0], "passphrase_attempts") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->psw_attempts_string, p[1], sizeof(options->psw_attempts_string) - 1);
|
||||
}
|
||||
else if (streq (p[0], "connectscript_timeout") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->connectscript_timeout_string, p[1], sizeof(options->connectscript_timeout_string) - 1);
|
||||
}
|
||||
else if (streq (p[0], "disconnectscript_timeout") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->disconnectscript_timeout_string, p[1],
|
||||
sizeof(options->disconnectscript_timeout_string) - 1);
|
||||
}
|
||||
else if (streq (p[0], "preconnectscript_timeout") && p[1])
|
||||
{
|
||||
++i;
|
||||
strncpy(options->preconnectscript_timeout_string, p[1],
|
||||
sizeof(options->preconnectscript_timeout_string) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unrecognized option or missing parameter */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_BAD_OPTION, p[0]);
|
||||
exit(1);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if option exist in config file.
|
||||
*/
|
||||
int ConfigFileOptionExist(int config, const char *option)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
int found_key=0;
|
||||
int found_pkcs12=0;
|
||||
char configfile_path[MAX_PATH];
|
||||
|
||||
strncpy(configfile_path, o.cnn[config].config_dir, sizeof(configfile_path));
|
||||
if (!(configfile_path[strlen(configfile_path)-1] == '\\'))
|
||||
strcat(configfile_path, "\\");
|
||||
strncat(configfile_path, o.cnn[config].config_file,
|
||||
sizeof(configfile_path) - strlen(configfile_path) - 1);
|
||||
|
||||
if (!(fp=fopen(configfile_path, "r")))
|
||||
{
|
||||
/* can't open config file */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_CONFIG, configfile_path);
|
||||
return(0);
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof (line), fp))
|
||||
{
|
||||
if ((strncmp(line, option, sizeof(option)) == 0))
|
||||
{
|
||||
fclose(fp);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
* Maximum number of parameters associated with an option,
|
||||
* including the option name itself.
|
||||
*/
|
||||
#define MAX_PARMS 5
|
||||
#define MAX_CONFIGS 50 /* Max number of config-files to read. */
|
||||
#define MAX_CONFIG_SUBDIRS 50 /* Max number of subdirs to scan */
|
||||
|
||||
/* connect_status STATES */
|
||||
#define DISCONNECTED 0
|
||||
#define CONNECTING 1
|
||||
#define CONNECTED 2
|
||||
#define RECONNECTING 3
|
||||
#define DISCONNECTING 4
|
||||
#define SUSPENDING 5
|
||||
#define SUSPENDED 6
|
||||
|
||||
/* OpenVPN Service STATES */
|
||||
#define SERVICE_NOACCESS -1
|
||||
#define SERVICE_DISCONNECTED 0
|
||||
#define SERVICE_CONNECTING 1
|
||||
#define SERVICE_CONNECTED 2
|
||||
|
||||
/* Connections parameters */
|
||||
struct connections
|
||||
{
|
||||
char config_file[MAX_PATH]; /* Name of the config file */
|
||||
char config_name[MAX_PATH]; /* Name of the connection */
|
||||
char config_dir[MAX_PATH]; /* Path to this configs dir */
|
||||
char log_path[MAX_PATH]; /* Path to Logfile */
|
||||
char ip[16]; /* Assigned IP address for this connection */
|
||||
char exit_event_name[50]; /* Exit Event name for this connection */
|
||||
int connect_status; /* 0=Not Connected 1=Connecting
|
||||
2=Connected 3=Reconnecting 4=Disconnecting */
|
||||
int auto_connect; /* true=AutoConnect at startup */
|
||||
int failed_psw; /* 1=OpenVPN failed because of wrong psw */
|
||||
int failed_psw_attempts; /* # of failed attempts maid to enter psw */
|
||||
int restart; /* true=Restart connection after termination */
|
||||
time_t connected_since; /* Time when the connection was established */
|
||||
|
||||
HANDLE exit_event;
|
||||
HANDLE hProcess;
|
||||
HANDLE hStdOut;
|
||||
HANDLE hStdIn;
|
||||
HWND hwndStatus; /* Handle to Status Dialog Window */
|
||||
};
|
||||
|
||||
/* All options used within OpenVPN GUI */
|
||||
struct options
|
||||
{
|
||||
/* Array of configs to autostart */
|
||||
const char *auto_connect[MAX_CONFIGS];
|
||||
|
||||
/* Connection parameters */
|
||||
struct connections cnn[MAX_CONFIGS]; /* Connection structure */
|
||||
int num_configs; /* Number of configs */
|
||||
|
||||
int oldversion; /* 1=OpenVPN version below 2.0-beta6 */
|
||||
char connect_string[100]; /* String to look for to report connected */
|
||||
int psw_attempts; /* Number of psw attemps to allow */
|
||||
int connectscript_timeout; /* Connect Script execution timeout (sec) */
|
||||
int disconnectscript_timeout; /* Disconnect Script execution timeout (sec) */
|
||||
int preconnectscript_timeout; /* Preconnect Script execution timeout (sec) */
|
||||
int service_running; /* true if OpenVPN Service is started */
|
||||
HWND hWnd; /* Main Window Handle */
|
||||
HINSTANCE hInstance;
|
||||
|
||||
/* Registry values */
|
||||
char exe_path[MAX_PATH];
|
||||
char config_dir[MAX_PATH];
|
||||
char ext_string[16];
|
||||
char log_dir[MAX_PATH];
|
||||
char priority_string[64];
|
||||
char append_string[2];
|
||||
char log_viewer[MAX_PATH];
|
||||
char editor[MAX_PATH];
|
||||
char allow_edit[2];
|
||||
char allow_service[2];
|
||||
char allow_password[2];
|
||||
char allow_proxy[2];
|
||||
char silent_connection[2];
|
||||
char service_only[2];
|
||||
char show_balloon[2];
|
||||
char show_script_window[2];
|
||||
char psw_attempts_string[2];
|
||||
char disconnect_on_suspend[2];
|
||||
char connectscript_timeout_string[4];
|
||||
char disconnectscript_timeout_string[4];
|
||||
char preconnectscript_timeout_string[4];
|
||||
|
||||
/* Proxy Settings */
|
||||
int proxy_source; /* 0=OpenVPN config, 1=IE, 2=Manual */
|
||||
int proxy_type; /* 0=HTTP, 1=SOCKS */
|
||||
int proxy_http_auth; /* 0=Auth Disabled, 1=Auth Enabled */
|
||||
char proxy_http_address[100]; /* HTTP Proxy Address */
|
||||
char proxy_http_port[6]; /* HTTP Proxy Port */
|
||||
char proxy_socks_address[100]; /* SOCKS Proxy Address */
|
||||
char proxy_socks_port[6]; /* SOCKS Proxy Address */
|
||||
char proxy_authfile[100]; /* Path to proxy auth file */
|
||||
|
||||
/* Debug file pointer */
|
||||
#ifdef DEBUG
|
||||
FILE *debug_fp;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define streq(x, y) (!strcmp((x), (y)))
|
||||
void init_options (struct options *o);
|
||||
int Createargcargv(struct options* options, char* command_line);
|
||||
void parse_argv (struct options* options, int argc, char *argv[]);
|
||||
static int add_option (struct options *options, int i, char *p[]);
|
||||
int ConfigFileOptionExist(int config, const char *option);
|
|
@ -0,0 +1,902 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "passphrase.h"
|
||||
#include "openvpn.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
#include "chartable.h"
|
||||
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
#endif
|
||||
|
||||
WCHAR passphrase[256];
|
||||
extern struct options o;
|
||||
|
||||
int ConvertUnicode2Ascii(WCHAR str_unicode[], char str_ascii[], unsigned int str_ascii_size)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
int illegal_chars = false;
|
||||
char *str_unicode_ptr = (char *) str_unicode;
|
||||
for (i=0; (i < wcslen(str_unicode)) && (i < (str_ascii_size - 1)); i++)
|
||||
{
|
||||
for (j=0; j <= 256; j++)
|
||||
{
|
||||
if (j == 256)
|
||||
{
|
||||
illegal_chars = true;
|
||||
j = 0x2e;
|
||||
break;
|
||||
}
|
||||
if (str_unicode[i] == unicode_to_ascii[j]) break;
|
||||
}
|
||||
str_ascii[i] = (char) j;
|
||||
}
|
||||
str_ascii[i] = '\0';
|
||||
|
||||
if (illegal_chars)
|
||||
return(false);
|
||||
else
|
||||
return(true);
|
||||
}
|
||||
|
||||
void CheckPrivateKeyPassphrasePrompt (char *line, int config)
|
||||
{
|
||||
DWORD nCharsWritten;
|
||||
char passphrase_ascii[256];
|
||||
|
||||
/* Check for Passphrase prompt */
|
||||
if (strncmp(line, "Enter PEM pass phrase:", 22) == 0)
|
||||
{
|
||||
CLEAR(passphrase);
|
||||
if (DialogBox(o.hInstance, (LPCTSTR)IDD_PASSPHRASE, NULL,
|
||||
(DLGPROC)PassphraseDialogFunc) == IDCANCEL)
|
||||
{
|
||||
StopOpenVPN(config);
|
||||
}
|
||||
|
||||
if (wcslen(passphrase) > 0)
|
||||
{
|
||||
CLEAR(passphrase_ascii);
|
||||
ConvertUnicode2Ascii(passphrase, passphrase_ascii, sizeof(passphrase_ascii));
|
||||
|
||||
if (!WriteFile(o.cnn[config].hStdIn, passphrase_ascii,
|
||||
strlen(passphrase_ascii), &nCharsWritten, NULL))
|
||||
{
|
||||
/* PassPhrase -> stdin failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_PASSPHRASE2STDIN, "");
|
||||
}
|
||||
}
|
||||
if (!WriteFile(o.cnn[config].hStdIn, "\r\n",
|
||||
2, &nCharsWritten, NULL))
|
||||
{
|
||||
/* CR -> stdin failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
|
||||
}
|
||||
/* Remove Passphrase prompt from lastline buffer */
|
||||
line[0]='\0';
|
||||
|
||||
/* Clear passphrase buffer */
|
||||
CLEAR(passphrase);
|
||||
CLEAR(passphrase_ascii);
|
||||
}
|
||||
|
||||
/* Check for new passphrase prompt introduced with OpenVPN 2.0-beta12. */
|
||||
if (strncmp(line, "Enter Private Key Password:", 27) == 0)
|
||||
{
|
||||
CLEAR(passphrase);
|
||||
if (DialogBox(o.hInstance, (LPCTSTR)IDD_PASSPHRASE, NULL,
|
||||
(DLGPROC)PassphraseDialogFunc) == IDCANCEL)
|
||||
{
|
||||
StopOpenVPN(config);
|
||||
}
|
||||
|
||||
if (wcslen(passphrase) > 0)
|
||||
{
|
||||
CLEAR(passphrase_ascii);
|
||||
ConvertUnicode2Ascii(passphrase, passphrase_ascii, sizeof(passphrase_ascii));
|
||||
|
||||
if (!WriteFile(o.cnn[config].hStdIn, passphrase_ascii,
|
||||
strlen(passphrase_ascii), &nCharsWritten, NULL))
|
||||
{
|
||||
/* PassPhrase -> stdin failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_PASSPHRASE2STDIN, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!WriteFile(o.cnn[config].hStdIn, "\n",
|
||||
1, &nCharsWritten, NULL))
|
||||
{
|
||||
/* CR -> stdin failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
|
||||
}
|
||||
}
|
||||
/* Remove Passphrase prompt from lastline buffer */
|
||||
line[0]='\0';
|
||||
|
||||
/* Clear passphrase buffer */
|
||||
CLEAR(passphrase);
|
||||
CLEAR(passphrase_ascii);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CheckAuthUsernamePrompt (char *line, int config)
|
||||
{
|
||||
DWORD nCharsWritten;
|
||||
struct user_auth user_auth;
|
||||
|
||||
/* Check for Passphrase prompt */
|
||||
if (strncmp(line, "Enter Auth Username:", 20) == 0)
|
||||
{
|
||||
CLEAR(user_auth);
|
||||
if (DialogBoxParam(o.hInstance,
|
||||
(LPCTSTR)IDD_AUTH_PASSWORD,
|
||||
NULL,
|
||||
(DLGPROC)AuthPasswordDialogFunc,
|
||||
(LPARAM)&user_auth) == IDCANCEL)
|
||||
{
|
||||
StopOpenVPN(config);
|
||||
}
|
||||
|
||||
if (strlen(user_auth.username) > 0)
|
||||
{
|
||||
if (!WriteFile(o.cnn[config].hStdIn, user_auth.username,
|
||||
strlen(user_auth.username), &nCharsWritten, NULL))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_AUTH_USERNAME2STDIN, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!WriteFile(o.cnn[config].hStdIn, "\n",
|
||||
1, &nCharsWritten, NULL))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(user_auth.password) > 0)
|
||||
{
|
||||
if (!WriteFile(o.cnn[config].hStdIn, user_auth.password,
|
||||
strlen(user_auth.password), &nCharsWritten, NULL))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_AUTH_PASSWORD2STDIN, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!WriteFile(o.cnn[config].hStdIn, "\n",
|
||||
1, &nCharsWritten, NULL))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CR2STDIN, "");
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove Username prompt from lastline buffer */
|
||||
line[0]='\0';
|
||||
|
||||
/* Clear user_auth buffer */
|
||||
CLEAR(user_auth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CheckAuthPasswordPrompt (char *line)
|
||||
{
|
||||
|
||||
/* Check for Passphrase prompt */
|
||||
if (strncmp(line, "Enter Auth Password:", 20) == 0)
|
||||
{
|
||||
|
||||
/* Remove Passphrase prompt from lastline buffer */
|
||||
line[0]='\0';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CALLBACK PassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
|
||||
{
|
||||
static char empty_string[100];
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
SetForegroundWindow(hwndDlg);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK: // button
|
||||
GetDlgItemTextW(hwndDlg, EDIT_PASSPHRASE, passphrase, sizeof(passphrase)/2 - 1);
|
||||
|
||||
/* Clear buffer */
|
||||
SetDlgItemText(hwndDlg, EDIT_PASSPHRASE, empty_string);
|
||||
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL: // button
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK AuthPasswordDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static struct user_auth *user_auth;
|
||||
static char empty_string[100];
|
||||
WCHAR username_unicode[50];
|
||||
WCHAR password_unicode[50];
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
user_auth = (struct user_auth *) lParam;
|
||||
SetForegroundWindow(hwndDlg);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK: // button
|
||||
GetDlgItemTextW(hwndDlg, EDIT_AUTH_USERNAME, username_unicode, sizeof(username_unicode)/2 - 1);
|
||||
GetDlgItemTextW(hwndDlg, EDIT_AUTH_PASSWORD, password_unicode, sizeof(password_unicode)/2 - 1);
|
||||
|
||||
/* Convert username/password from Unicode to Ascii (CP850) */
|
||||
ConvertUnicode2Ascii(username_unicode, user_auth->username, sizeof(user_auth->username) - 1);
|
||||
ConvertUnicode2Ascii(password_unicode, user_auth->password, sizeof(user_auth->password) - 1);
|
||||
|
||||
/* Clear buffers */
|
||||
SetDlgItemText(hwndDlg, EDIT_AUTH_USERNAME, empty_string);
|
||||
SetDlgItemText(hwndDlg, EDIT_AUTH_PASSWORD, empty_string);
|
||||
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL: // button
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
|
||||
const int KEYFILE_FORMAT_PKCS12 = 1;
|
||||
const int KEYFILE_FORMAT_PEM = 2;
|
||||
|
||||
void ShowChangePassphraseDialog(int config)
|
||||
{
|
||||
HANDLE hThread;
|
||||
DWORD IDThread;
|
||||
|
||||
/* Start a new thread to have our own message-loop for this dialog */
|
||||
hThread = CreateThread(NULL, 0,
|
||||
(LPTHREAD_START_ROUTINE) ChangePassphraseThread,
|
||||
(int *) config, // pass config nr
|
||||
0, &IDThread);
|
||||
if (hThread == NULL)
|
||||
{
|
||||
/* error creating thread */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_CREATE_PASS_THREAD, "");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ChangePassphraseThread(int config)
|
||||
{
|
||||
HWND hwndChangePSW;
|
||||
MSG messages;
|
||||
char conn_name[100];
|
||||
char msg[100];
|
||||
char keyfilename[MAX_PATH];
|
||||
int keyfile_format=0;
|
||||
TCHAR buf[1000];
|
||||
|
||||
/* Cut of extention from config filename. */
|
||||
strncpy(conn_name, o.cnn[config].config_file, sizeof(conn_name));
|
||||
conn_name[strlen(conn_name) - (strlen(o.ext_string)+1)]=0;
|
||||
|
||||
/* Get Key filename from config file */
|
||||
if (!GetKeyFilename(config, keyfilename, sizeof(keyfilename), &keyfile_format))
|
||||
{
|
||||
ExitThread(1);
|
||||
}
|
||||
|
||||
/* Show ChangePassphrase Dialog */
|
||||
if (!(hwndChangePSW = CreateDialog (o.hInstance,
|
||||
MAKEINTRESOURCE (IDD_CHANGEPSW),
|
||||
NULL, (DLGPROC) ChangePassphraseDialogFunc)))
|
||||
return;
|
||||
SetDlgItemText(hwndChangePSW, TEXT_KEYFILE, keyfilename);
|
||||
SetDlgItemInt(hwndChangePSW, TEXT_KEYFORMAT, (UINT) keyfile_format, FALSE);
|
||||
|
||||
myLoadString(INFO_CHANGE_PWD);
|
||||
mysnprintf(msg, buf, conn_name);
|
||||
SetWindowText(hwndChangePSW, msg);
|
||||
|
||||
ShowWindow(hwndChangePSW, SW_SHOW);
|
||||
|
||||
|
||||
/* Run the message loop. It will run until GetMessage() returns 0 */
|
||||
while (GetMessage (&messages, NULL, 0, 0))
|
||||
{
|
||||
if(!IsDialogMessage(hwndChangePSW, &messages))
|
||||
{
|
||||
TranslateMessage(&messages);
|
||||
DispatchMessage(&messages);
|
||||
}
|
||||
}
|
||||
|
||||
ExitThread(0);
|
||||
}
|
||||
|
||||
BOOL CALLBACK ChangePassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
|
||||
{
|
||||
HICON hIcon;
|
||||
char keyfile[MAX_PATH];
|
||||
int keyfile_format;
|
||||
BOOL Translated;
|
||||
TCHAR buf[1000];
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
|
||||
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
if (hIcon) {
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK:
|
||||
|
||||
/* Check if the type new passwords match. */
|
||||
if (!ConfirmNewPassword (hwndDlg))
|
||||
{
|
||||
/* passwords don't match */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_PWD_DONT_MATCH, "");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check minimum length of password */
|
||||
if (NewPasswordLengh(hwndDlg) < MIN_PASSWORD_LEN)
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_PWD_TO_SHORT, MIN_PASSWORD_LEN);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if the new password is empty. */
|
||||
if (NewPasswordLengh(hwndDlg) == 0)
|
||||
{
|
||||
myLoadString(INFO_EMPTY_PWD);
|
||||
if (MessageBox(NULL, buf, GUI_NAME, MB_YESNO) != IDYES)
|
||||
break;
|
||||
}
|
||||
|
||||
GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1);
|
||||
keyfile_format=GetDlgItemInt(hwndDlg, TEXT_KEYFORMAT, &Translated, FALSE);
|
||||
if (keyfile_format == KEYFILE_FORMAT_PEM)
|
||||
{
|
||||
/* Change password of a PEM file */
|
||||
if (ChangePasswordPEM(hwndDlg) == -1) /* Wrong password */
|
||||
break;
|
||||
}
|
||||
else if (keyfile_format == KEYFILE_FORMAT_PKCS12)
|
||||
{
|
||||
/* Change password of a .P12 file */
|
||||
if (ChangePasswordPKCS12(hwndDlg) == -1) /* Wrong password */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unknown key format */
|
||||
ShowLocalizedMsg (GUI_NAME, ERR_UNKNOWN_KEYFILE_FORMAT, "");
|
||||
}
|
||||
|
||||
DestroyWindow(hwndDlg);
|
||||
break;
|
||||
|
||||
case IDCANCEL:
|
||||
DestroyWindow(hwndDlg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwndDlg);
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Return TRUE if new passwords match */
|
||||
int ConfirmNewPassword(HWND hwndDlg)
|
||||
{
|
||||
char newpsw[50];
|
||||
char newpsw2[50];
|
||||
|
||||
GetDlgItemText(hwndDlg, EDIT_PSW_NEW, newpsw, sizeof(newpsw) - 1);
|
||||
GetDlgItemText(hwndDlg, EDIT_PSW_NEW2, newpsw2, sizeof(newpsw2) - 1);
|
||||
|
||||
if (strncmp(newpsw, newpsw2, sizeof(newpsw)) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return lengh of the new password */
|
||||
int NewPasswordLengh(HWND hwndDlg)
|
||||
{
|
||||
char newpsw[50];
|
||||
|
||||
GetDlgItemText(hwndDlg, EDIT_PSW_NEW, newpsw, sizeof(newpsw) - 1);
|
||||
|
||||
return (strlen(newpsw));
|
||||
}
|
||||
|
||||
int ParseKeyFilenameLine(int config, char *keyfilename, unsigned int keyfilenamesize, char *line)
|
||||
{
|
||||
const int STATE_INITIAL = 0;
|
||||
const int STATE_READING_QUOTED_PARM = 1;
|
||||
const int STATE_READING_UNQUOTED_PARM = 2;
|
||||
int i=0;
|
||||
unsigned int j=0;
|
||||
int state = STATE_INITIAL;
|
||||
int backslash=0;
|
||||
char temp_filename[MAX_PATH];
|
||||
|
||||
while(line[i] != '\0')
|
||||
{
|
||||
if (state == STATE_INITIAL)
|
||||
{
|
||||
if (line[i] == '\"')
|
||||
{
|
||||
state=STATE_READING_QUOTED_PARM;
|
||||
}
|
||||
else if ((line[i] == 0x0A) || (line[i] == 0x0D))
|
||||
break;
|
||||
else if ((line[i] == ';') || (line[i] == '#'))
|
||||
break;
|
||||
else if ((line[i] != ' ') && (line[i] != '\t'))
|
||||
{
|
||||
if (line[i] == '\\')
|
||||
{
|
||||
if(!backslash)
|
||||
{
|
||||
keyfilename[j++]=line[i];
|
||||
state=STATE_READING_UNQUOTED_PARM;
|
||||
backslash=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
backslash=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (backslash) backslash=0;
|
||||
keyfilename[j++]=line[i];
|
||||
state=STATE_READING_UNQUOTED_PARM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (state == STATE_READING_QUOTED_PARM)
|
||||
{
|
||||
if (line[i] == '\"')
|
||||
break;
|
||||
if ((line[i] == 0x0A) || (line[i] == 0x0D))
|
||||
break;
|
||||
if (line[i] == '\\')
|
||||
{
|
||||
if (!backslash)
|
||||
{
|
||||
keyfilename[j++]=line[i];
|
||||
backslash=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
backslash=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (backslash) backslash=0;
|
||||
keyfilename[j++]=line[i];
|
||||
}
|
||||
}
|
||||
|
||||
else if (state == STATE_READING_UNQUOTED_PARM)
|
||||
{
|
||||
if (line[i] == '\"')
|
||||
break;
|
||||
if ((line[i] == 0x0A) || (line[i] == 0x0D))
|
||||
break;
|
||||
if ((line[i] == ';') || (line[i] == '#'))
|
||||
break;
|
||||
if (line[i] == ' ')
|
||||
break;
|
||||
if (line[i] == '\t')
|
||||
break;
|
||||
if (line[i] == '\\')
|
||||
{
|
||||
if (!backslash)
|
||||
{
|
||||
keyfilename[j++]=line[i];
|
||||
backslash=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
backslash=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (backslash) backslash=0;
|
||||
keyfilename[j++]=line[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (j >= (keyfilenamesize - 1))
|
||||
{
|
||||
/* key filename to long */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_KEY_FILENAME_TO_LONG, "");
|
||||
return(0);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
keyfilename[j]='\0';
|
||||
|
||||
/* Prepend filename with configdir path if needed */
|
||||
if ((keyfilename[0] != '\\') && (keyfilename[0] != '/') && (keyfilename[1] != ':'))
|
||||
{
|
||||
strncpy(temp_filename, o.cnn[config].config_dir, sizeof(temp_filename));
|
||||
if (temp_filename[strlen(temp_filename) - 1] != '\\')
|
||||
strcat(temp_filename, "\\");
|
||||
strncat(temp_filename, keyfilename,
|
||||
sizeof(temp_filename) - strlen(temp_filename) - 1);
|
||||
strncpy(keyfilename, temp_filename, keyfilenamesize - 1);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ChangePasswordPEM() returns:
|
||||
* -1 Wrong password
|
||||
* 0 Changing password failed for unknown reason
|
||||
* 1 Password changed successfully
|
||||
*/
|
||||
int ChangePasswordPEM(HWND hwndDlg)
|
||||
{
|
||||
char keyfile[MAX_PATH];
|
||||
char oldpsw[50];
|
||||
char newpsw[50];
|
||||
WCHAR oldpsw_unicode[50];
|
||||
WCHAR newpsw_unicode[50];
|
||||
FILE *fp;
|
||||
|
||||
EVP_PKEY *privkey;
|
||||
|
||||
/* Get filename, old_psw and new_psw from Dialog */
|
||||
GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1);
|
||||
GetDlgItemTextW(hwndDlg, EDIT_PSW_CURRENT, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
|
||||
GetDlgItemTextW(hwndDlg, EDIT_PSW_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1);
|
||||
|
||||
/* Convert Unicode to ASCII (CP850) */
|
||||
ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
|
||||
if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_INVALID_CHARS_IN_PSW, "");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
privkey = EVP_PKEY_new();
|
||||
|
||||
/* Open old keyfile for reading */
|
||||
if (! (fp = fopen (keyfile, "r")))
|
||||
{
|
||||
/* can't open key file */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Import old key */
|
||||
if (! (privkey = PEM_read_PrivateKey (fp, NULL, NULL, oldpsw)))
|
||||
{
|
||||
/* wrong password */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OLD_PWD_INCORRECT, "");
|
||||
fclose(fp);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* Open keyfile for writing */
|
||||
if (! (fp = fopen (keyfile, "w")))
|
||||
{
|
||||
/* can't open file rw */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_WRITE_KEY, keyfile);
|
||||
EVP_PKEY_free(privkey);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Write new key to file */
|
||||
if (strlen(newpsw) == 0)
|
||||
{
|
||||
/* No passphrase */
|
||||
if ( !(PEM_write_PrivateKey(fp, privkey, \
|
||||
NULL, NULL, /* Use NO encryption */
|
||||
0, 0, NULL)))
|
||||
{
|
||||
/* error writing new key */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_WRITE_NEW_KEY, keyfile);
|
||||
EVP_PKEY_free(privkey);
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use passphrase */
|
||||
if ( !(PEM_write_PrivateKey(fp, privkey, \
|
||||
EVP_des_ede3_cbc(), /* Use 3DES encryption */
|
||||
newpsw, (int) strlen(newpsw), 0, NULL)))
|
||||
{
|
||||
/* can't write new key */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_WRITE_NEW_KEY, keyfile);
|
||||
EVP_PKEY_free(privkey);
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
EVP_PKEY_free(privkey);
|
||||
fclose(fp);
|
||||
|
||||
/* signal success to user */
|
||||
ShowLocalizedMsg(GUI_NAME, INFO_PWD_CHANGED, "");
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ChangePasswordPKCS12() returns:
|
||||
* -1 Wrong password
|
||||
* 0 Changing password failed for unknown reason
|
||||
* 1 Password changed successfully
|
||||
*/
|
||||
int ChangePasswordPKCS12(HWND hwndDlg)
|
||||
{
|
||||
char keyfile[MAX_PATH];
|
||||
char oldpsw[50];
|
||||
char newpsw[50];
|
||||
WCHAR oldpsw_unicode[50];
|
||||
WCHAR newpsw_unicode[50];
|
||||
FILE *fp;
|
||||
|
||||
EVP_PKEY *privkey;
|
||||
X509 *cert;
|
||||
STACK_OF(X509) *ca = NULL;
|
||||
PKCS12 *p12;
|
||||
PKCS12 *new_p12;
|
||||
char *alias;
|
||||
|
||||
/* Get filename, old_psw and new_psw from Dialog */
|
||||
GetDlgItemText(hwndDlg, TEXT_KEYFILE, keyfile, sizeof(keyfile) - 1);
|
||||
GetDlgItemTextW(hwndDlg, EDIT_PSW_CURRENT, oldpsw_unicode, sizeof(oldpsw_unicode)/2 - 1);
|
||||
GetDlgItemTextW(hwndDlg, EDIT_PSW_NEW, newpsw_unicode, sizeof(newpsw_unicode)/2 - 1);
|
||||
|
||||
/* Convert Unicode to ASCII (CP850) */
|
||||
ConvertUnicode2Ascii(oldpsw_unicode, oldpsw, sizeof(oldpsw));
|
||||
if (!ConvertUnicode2Ascii(newpsw_unicode, newpsw, sizeof(newpsw)))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_INVALID_CHARS_IN_PSW, "");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Load the PKCS #12 file */
|
||||
if (!(fp = fopen(keyfile, "rb")))
|
||||
{
|
||||
/* error opening file */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_PRIVATE_KEY_FILE, keyfile);
|
||||
return(0);
|
||||
}
|
||||
p12 = d2i_PKCS12_fp(fp, NULL);
|
||||
fclose (fp);
|
||||
if (!p12)
|
||||
{
|
||||
/* error reading PKCS #12 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_READ_PKCS12, keyfile);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Parse the PKCS #12 file */
|
||||
if (!PKCS12_parse(p12, oldpsw, &privkey, &cert, &ca))
|
||||
{
|
||||
/* old password incorrect */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OLD_PWD_INCORRECT, "");
|
||||
PKCS12_free(p12);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Free old PKCS12 object */
|
||||
PKCS12_free(p12);
|
||||
|
||||
/* Get FriendlyName of old cert */
|
||||
alias = X509_alias_get0(cert, NULL);
|
||||
|
||||
/* Create new PKCS12 object */
|
||||
p12 = PKCS12_create(newpsw, alias, privkey, cert, ca, 0,0,0,0,0);
|
||||
if (!p12)
|
||||
{
|
||||
/* create failed */
|
||||
//ShowMsg(GUI_NAME, ERR_error_string(ERR_peek_last_error(), NULL));
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_PKCS12, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Free old key, cert and ca */
|
||||
EVP_PKEY_free(privkey);
|
||||
X509_free(cert);
|
||||
sk_X509_pop_free(ca, X509_free);
|
||||
|
||||
/* Open keyfile for writing */
|
||||
if (!(fp = fopen(keyfile, "wb")))
|
||||
{
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_WRITE_KEY, keyfile);
|
||||
PKCS12_free(p12);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Write new key to file */
|
||||
i2d_PKCS12_fp(fp, p12);
|
||||
|
||||
PKCS12_free(p12);
|
||||
fclose(fp);
|
||||
/* signal success to user */
|
||||
ShowLocalizedMsg(GUI_NAME, INFO_PWD_CHANGED, "");
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
int LineBeginsWith(char *line, const char *keyword, const unsigned int len)
|
||||
{
|
||||
if (strncmp(line, keyword, len) == 0)
|
||||
{
|
||||
if ((line[len] == '\t') || (line[len] == ' '))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int GetKeyFilename(int config, char *keyfilename, unsigned int keyfilenamesize, int *keyfile_format)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[256];
|
||||
int found_key=0;
|
||||
int found_pkcs12=0;
|
||||
char configfile_path[MAX_PATH];
|
||||
|
||||
strncpy(configfile_path, o.cnn[config].config_dir, sizeof(configfile_path));
|
||||
if (!(configfile_path[strlen(configfile_path)-1] == '\\'))
|
||||
strcat(configfile_path, "\\");
|
||||
strncat(configfile_path, o.cnn[config].config_file,
|
||||
sizeof(configfile_path) - strlen(configfile_path) - 1);
|
||||
|
||||
if (!(fp=fopen(configfile_path, "r")))
|
||||
{
|
||||
/* can't open config file */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_CONFIG, configfile_path);
|
||||
return(0);
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof (line), fp))
|
||||
{
|
||||
if (LineBeginsWith(line, "key", 3))
|
||||
{
|
||||
if (found_key)
|
||||
{
|
||||
/* only one key option */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_ONE_KEY_OPTION, "");
|
||||
return(0);
|
||||
}
|
||||
if (found_pkcs12)
|
||||
{
|
||||
/* key XOR pkcs12 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_KEY_OR_PKCS12, "");
|
||||
return(0);
|
||||
}
|
||||
found_key=1;
|
||||
*keyfile_format = KEYFILE_FORMAT_PEM;
|
||||
if (!ParseKeyFilenameLine(config, keyfilename, keyfilenamesize, &line[4]))
|
||||
return(0);
|
||||
}
|
||||
if (LineBeginsWith(line, "pkcs12", 6))
|
||||
{
|
||||
if (found_pkcs12)
|
||||
{
|
||||
/* only one pkcs12 option */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_ONE_PKCS12_OPTION, "");
|
||||
return(0);
|
||||
}
|
||||
if (found_key)
|
||||
{
|
||||
/* only key XOR pkcs12 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_ONLY_KEY_OR_PKCS12, "");
|
||||
return(0);
|
||||
}
|
||||
found_pkcs12=1;
|
||||
*keyfile_format = KEYFILE_FORMAT_PKCS12;
|
||||
if (!ParseKeyFilenameLine(config, keyfilename, keyfilenamesize, &line[7]))
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!found_key) && (!found_pkcs12))
|
||||
{
|
||||
/* must have key or pkcs12 option */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_MUST_HAVE_KEY_OR_PKCS12, "");
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
#define MIN_PASSWORD_LEN 8
|
||||
|
||||
struct user_auth {
|
||||
char username[50];
|
||||
char password[50];
|
||||
};
|
||||
|
||||
void CheckPrivateKeyPassphrasePrompt (char *line, int config);
|
||||
void CheckAuthUsernamePrompt (char *line, int config);
|
||||
void CheckAuthPasswordPrompt (char *line);
|
||||
BOOL CALLBACK PassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK AuthPasswordDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void ShowChangePassphraseDialog(int config);
|
||||
BOOL CALLBACK ChangePassphraseDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void ChangePassphraseThread(int config);
|
||||
int ConfirmNewPassword(HWND hwndDlg);
|
||||
int NewPasswordLengh(HWND hwndDlg);
|
||||
int ChangePasswordPEM(HWND hwndDlg);
|
||||
int ChangePasswordPKCS12(HWND hwndDlg);
|
||||
int GetKeyFilename(int config, char *keyfilename, unsigned int keyfilenamesize, int *keyfile_format);
|
||||
|
|
@ -0,0 +1,569 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "registry.h"
|
||||
#include "proxy.h"
|
||||
#include "ieproxy.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
void ShowProxySettingsDialog()
|
||||
{
|
||||
|
||||
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY, NULL, (DLGPROC)ProxySettingsDialogFunc);
|
||||
}
|
||||
|
||||
BOOL CALLBACK ProxySettingsDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
|
||||
{
|
||||
HICON hIcon;
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
|
||||
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
if (hIcon) {
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
|
||||
SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon));
|
||||
}
|
||||
|
||||
/* Limit Port editboxs to 5 chars. */
|
||||
SendMessage(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), EM_SETLIMITTEXT, 5, 0);
|
||||
SendMessage(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), EM_SETLIMITTEXT, 5, 0);
|
||||
|
||||
LoadProxySettings(hwndDlg);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK:
|
||||
if (CheckProxySettings(hwndDlg))
|
||||
{
|
||||
SaveProxySettings(hwndDlg);
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
case RB_PROXY_USE_OPENVPN:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_HTTP), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_SOCKS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case RB_PROXY_USE_IE:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_HTTP), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_SOCKS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case RB_PROXY_USE_MANUAL:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_HTTP), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_SOCKS), TRUE);
|
||||
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_HTTP) == BST_CHECKED)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case RB_PROXY_HTTP:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
case RB_PROXY_SOCKS:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_ADDRESS), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_HTTP_PORT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, CHECKB_PROXY_AUTH), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, EDIT_PROXY_SOCKS_PORT), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_ADDRESS), TRUE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, TEXT_PROXY_SOCKS_PORT), TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check that proxy settings are valid */
|
||||
int CheckProxySettings(HWND hwndDlg)
|
||||
{
|
||||
char text[100];
|
||||
long port;
|
||||
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_MANUAL) == BST_CHECKED)
|
||||
{
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_HTTP) == BST_CHECKED)
|
||||
{
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_ADDRESS, text, sizeof(text));
|
||||
if (strlen(text) == 0)
|
||||
{
|
||||
/* http_proxy_access not specified */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_HTTP_PROXY_ADDRESS, "");
|
||||
return(0);
|
||||
}
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_PORT, text, sizeof(text));
|
||||
if (strlen(text) == 0)
|
||||
{
|
||||
/* http_proxy_port not specified */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_HTTP_PROXY_PORT, "");
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
port=strtol(text, NULL, 10);
|
||||
if ((port < 1) || (port > 65535))
|
||||
{
|
||||
/* http_proxy_port range error */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_HTTP_PROXY_PORT_RANGE, "");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_SOCKS) == BST_CHECKED)
|
||||
{
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS, text, sizeof(text));
|
||||
if (strlen(text) == 0)
|
||||
{
|
||||
/* socks_proxy_address not specified */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_SOCKS_PROXY_ADDRESS, "");
|
||||
return(0);
|
||||
}
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_PORT, text, sizeof(text));
|
||||
if (strlen(text) == 0)
|
||||
{
|
||||
/* socks_proxy_port not specified */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_SOCKS_PROXY_PORT, "");
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
port=strtol(text, NULL, 10);
|
||||
if ((port < 1) || (port > 65535))
|
||||
{
|
||||
/* socks_proxy_port range error */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_SOCKS_PROXY_PORT_RANGE, "");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
void LoadProxySettings(HWND hwndDlg)
|
||||
{
|
||||
|
||||
/* Disable IE Settings untill this is implemented */
|
||||
// EnableWindow(GetDlgItem(hwndDlg, RB_PROXY_USE_IE), FALSE);
|
||||
|
||||
/* Set Proxy Type */
|
||||
if (o.proxy_type == 0) /* HTTP Proxy */
|
||||
{
|
||||
CheckRadioButton(hwndDlg,
|
||||
RB_PROXY_HTTP, /* First button in group */
|
||||
RB_PROXY_SOCKS, /* Last button in group */
|
||||
RB_PROXY_HTTP); /* Select this button */
|
||||
}
|
||||
else /* SOCKS Proxy */
|
||||
{
|
||||
CheckRadioButton(hwndDlg,
|
||||
RB_PROXY_HTTP, /* First button in group */
|
||||
RB_PROXY_SOCKS, /* Last button in group */
|
||||
RB_PROXY_SOCKS); /* Select this button */
|
||||
}
|
||||
|
||||
/* Set Proxy Settings Source */
|
||||
if (o.proxy_source == 0)
|
||||
SendMessage(GetDlgItem(hwndDlg, RB_PROXY_USE_OPENVPN), BM_CLICK, 0, 0);
|
||||
if (o.proxy_source == 1)
|
||||
SendMessage(GetDlgItem(hwndDlg, RB_PROXY_USE_IE), BM_CLICK, 0, 0);
|
||||
if (o.proxy_source == 2)
|
||||
SendMessage(GetDlgItem(hwndDlg, RB_PROXY_USE_MANUAL), BM_CLICK, 0, 0);
|
||||
|
||||
/* Set Proxy addresses and ports */
|
||||
SetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_ADDRESS, o.proxy_http_address);
|
||||
SetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_PORT, o.proxy_http_port);
|
||||
SetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS, o.proxy_socks_address);
|
||||
SetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_PORT, o.proxy_socks_port);
|
||||
if (o.proxy_http_auth) CheckDlgButton(hwndDlg, CHECKB_PROXY_AUTH, BST_CHECKED);
|
||||
}
|
||||
|
||||
void SaveProxySettings(HWND hwndDlg)
|
||||
{
|
||||
|
||||
LONG status;
|
||||
HKEY regkey;
|
||||
DWORD dwDispos;
|
||||
char proxy_source_string[2]="0";
|
||||
char proxy_type_string[2]="0";
|
||||
char proxy_http_auth_string[2]="0";
|
||||
|
||||
/* Save Proxy Settings Source */
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_OPENVPN) == BST_CHECKED)
|
||||
{
|
||||
o.proxy_source = 0;
|
||||
proxy_source_string[0] = '0';
|
||||
}
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_IE) == BST_CHECKED)
|
||||
{
|
||||
o.proxy_source = 1;
|
||||
proxy_source_string[0] = '1';
|
||||
}
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_USE_MANUAL) == BST_CHECKED)
|
||||
{
|
||||
o.proxy_source = 2;
|
||||
proxy_source_string[0] = '2';
|
||||
}
|
||||
|
||||
/* Save Proxy addresses and ports */
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_ADDRESS, o.proxy_http_address,
|
||||
sizeof(o.proxy_http_address));
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_HTTP_PORT, o.proxy_http_port,
|
||||
sizeof(o.proxy_http_port));
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_ADDRESS, o.proxy_socks_address,
|
||||
sizeof(o.proxy_http_address));
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_SOCKS_PORT, o.proxy_socks_port,
|
||||
sizeof(o.proxy_socks_port));
|
||||
|
||||
if (IsDlgButtonChecked(hwndDlg, RB_PROXY_HTTP) == BST_CHECKED)
|
||||
{
|
||||
o.proxy_type = 0;
|
||||
proxy_type_string[0] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
o.proxy_type = 1;
|
||||
proxy_type_string[0] = '1';
|
||||
}
|
||||
|
||||
if (IsDlgButtonChecked(hwndDlg, CHECKB_PROXY_AUTH) == BST_CHECKED)
|
||||
{
|
||||
o.proxy_http_auth = 1;
|
||||
proxy_http_auth_string[0] = '1';
|
||||
}
|
||||
else
|
||||
{
|
||||
o.proxy_http_auth = 0;
|
||||
proxy_http_auth_string[0] = '0';
|
||||
}
|
||||
|
||||
/* Open Registry for writing */
|
||||
if (RegCreateKeyEx(HKEY_CURRENT_USER,
|
||||
GUI_REGKEY_HKCU,
|
||||
0,
|
||||
(LPTSTR) "",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_WRITE,
|
||||
NULL,
|
||||
®key,
|
||||
&dwDispos) != ERROR_SUCCESS)
|
||||
{
|
||||
/* error creating Registry-Key */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save Settings to registry */
|
||||
SetRegistryValue(regkey, "proxy_source", proxy_source_string);
|
||||
SetRegistryValue(regkey, "proxy_type", proxy_type_string);
|
||||
SetRegistryValue(regkey, "proxy_http_auth", proxy_http_auth_string);
|
||||
SetRegistryValue(regkey, "proxy_http_address", o.proxy_http_address);
|
||||
SetRegistryValue(regkey, "proxy_http_port", o.proxy_http_port);
|
||||
SetRegistryValue(regkey, "proxy_socks_address", o.proxy_socks_address);
|
||||
SetRegistryValue(regkey, "proxy_socks_port", o.proxy_socks_port);
|
||||
|
||||
RegCloseKey(regkey);
|
||||
|
||||
}
|
||||
|
||||
void GetProxyRegistrySettings()
|
||||
{
|
||||
LONG status;
|
||||
HKEY regkey;
|
||||
char proxy_source_string[2]="0";
|
||||
char proxy_type_string[2]="0";
|
||||
char proxy_http_auth_string[2]="0";
|
||||
char temp_path[100];
|
||||
|
||||
/* Construct Authfile path */
|
||||
if (!GetTempPath(sizeof(temp_path) - 1, temp_path))
|
||||
{
|
||||
/* Error getting TempPath - using C:\ */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_GET_TEMP_PATH, "");
|
||||
strcpy(temp_path, "C:\\");
|
||||
}
|
||||
strncat(temp_path, "openvpn_authfile.txt",
|
||||
sizeof(temp_path) - strlen(temp_path) - 1);
|
||||
strncpy(o.proxy_authfile, temp_path, sizeof(o.proxy_authfile));
|
||||
|
||||
/* Open Registry for reading */
|
||||
status = RegOpenKeyEx(HKEY_CURRENT_USER,
|
||||
GUI_REGKEY_HKCU,
|
||||
0,
|
||||
KEY_READ,
|
||||
®key);
|
||||
|
||||
/* Return if can't open the registry key */
|
||||
if (status != ERROR_SUCCESS) return;
|
||||
|
||||
|
||||
/* get registry settings */
|
||||
GetRegistryValue(regkey, "proxy_http_address", o.proxy_http_address,
|
||||
sizeof(o.proxy_http_address));
|
||||
GetRegistryValue(regkey, "proxy_http_port", o.proxy_http_port,
|
||||
sizeof(o.proxy_http_port));
|
||||
GetRegistryValue(regkey, "proxy_socks_address", o.proxy_socks_address,
|
||||
sizeof(o.proxy_socks_address));
|
||||
GetRegistryValue(regkey, "proxy_socks_port", o.proxy_socks_port,
|
||||
sizeof(o.proxy_socks_port));
|
||||
GetRegistryValue(regkey, "proxy_source", proxy_source_string,
|
||||
sizeof(proxy_source_string));
|
||||
GetRegistryValue(regkey, "proxy_type", proxy_type_string,
|
||||
sizeof(proxy_type_string));
|
||||
GetRegistryValue(regkey, "proxy_http_auth", proxy_http_auth_string,
|
||||
sizeof(proxy_http_auth_string));
|
||||
|
||||
if (proxy_source_string[0] == '1')
|
||||
o.proxy_source=1;
|
||||
if (proxy_source_string[0] == '2')
|
||||
o.proxy_source=2;
|
||||
if (proxy_source_string[0] == '3')
|
||||
o.proxy_source=3;
|
||||
|
||||
if (proxy_type_string[0] == '1')
|
||||
o.proxy_type=1;
|
||||
|
||||
if (proxy_http_auth_string[0] == '1')
|
||||
o.proxy_http_auth=1;
|
||||
|
||||
RegCloseKey(regkey);
|
||||
return;
|
||||
}
|
||||
|
||||
BOOL CALLBACK ProxyAuthDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lParam)
|
||||
{
|
||||
char username[50];
|
||||
char password[50];
|
||||
FILE *fp;
|
||||
|
||||
switch (msg) {
|
||||
|
||||
case WM_INITDIALOG:
|
||||
//SetForegroundWindow(hwndDlg);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
|
||||
case IDOK:
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_USERNAME, username, sizeof(username) - 1);
|
||||
GetDlgItemText(hwndDlg, EDIT_PROXY_PASSWORD, password, sizeof(password) - 1);
|
||||
if (!(fp = fopen(o.proxy_authfile, "w")))
|
||||
{
|
||||
/* error creating AUTH file */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_AUTH_FILE, o.proxy_authfile);
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
}
|
||||
fputs(username, fp);
|
||||
fputs("\n", fp);
|
||||
fputs(password, fp);
|
||||
fputs("\n", fp);
|
||||
fclose(fp);
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct the proxy options to append to the cmd-line.
|
||||
*/
|
||||
void ConstructProxyCmdLine(char *proxy_string_ptr, unsigned int size)
|
||||
{
|
||||
char proxy_string[100];
|
||||
|
||||
CLEAR(proxy_string);
|
||||
|
||||
if (o.proxy_source == PROXY_SOURCE_MANUAL)
|
||||
{
|
||||
if (o.proxy_type == PROXY_TYPE_HTTP)
|
||||
{
|
||||
if (o.proxy_http_auth == PROXY_HTTP_ASK_AUTH)
|
||||
{
|
||||
/* Ask for Proxy username/password */
|
||||
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY_AUTH, NULL, (DLGPROC)ProxyAuthDialogFunc);
|
||||
mysnprintf(proxy_string, "--http-proxy %s %s %s",
|
||||
o.proxy_http_address,
|
||||
o.proxy_http_port,
|
||||
o.proxy_authfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf(proxy_string, "--http-proxy %s %s",
|
||||
o.proxy_http_address,
|
||||
o.proxy_http_port);
|
||||
}
|
||||
}
|
||||
if (o.proxy_type == PROXY_TYPE_SOCKS)
|
||||
{
|
||||
mysnprintf(proxy_string, "--socks-proxy %s %s",
|
||||
o.proxy_socks_address,
|
||||
o.proxy_socks_port);
|
||||
}
|
||||
}
|
||||
|
||||
if (o.proxy_source == PROXY_SOURCE_IE)
|
||||
{
|
||||
LPCTSTR ieproxy;
|
||||
char *pos;
|
||||
|
||||
ieproxy = getIeHttpProxy();
|
||||
if (!ieproxy)
|
||||
{
|
||||
/* can't get ie proxy settings */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_GET_IE_PROXY_SETTINGS, getIeHttpProxyError);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Don't use a proxy if IE proxy string is empty */
|
||||
if (strlen(ieproxy) > 1)
|
||||
{
|
||||
/* Parse the port number from the IE proxy string */
|
||||
if ((pos = strchr(ieproxy, ':')))
|
||||
{
|
||||
*pos = '\0';
|
||||
if (o.proxy_http_auth == PROXY_HTTP_ASK_AUTH)
|
||||
{
|
||||
/* Ask for Proxy username/password */
|
||||
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY_AUTH, NULL, (DLGPROC)ProxyAuthDialogFunc);
|
||||
mysnprintf(proxy_string, "--http-proxy %s %s %s",
|
||||
ieproxy, pos+1, o.proxy_authfile)
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf(proxy_string, "--http-proxy %s %s", ieproxy, pos+1)
|
||||
}
|
||||
}
|
||||
/* No port is specified, use 80 as default port */
|
||||
else
|
||||
{
|
||||
if (o.proxy_http_auth == PROXY_HTTP_ASK_AUTH)
|
||||
{
|
||||
/* Ask for Proxy username/password */
|
||||
DialogBox(o.hInstance, (LPCTSTR)IDD_PROXY_AUTH, NULL, (DLGPROC)ProxyAuthDialogFunc);
|
||||
mysnprintf(proxy_string, "--http-proxy %s 80 %s",
|
||||
ieproxy, o.proxy_authfile)
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf(proxy_string, "--http-proxy %s 80", ieproxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
//free (ieproxy);
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(proxy_string_ptr, proxy_string, size);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
#define PROXY_SOURCE_OPENVPN 0
|
||||
#define PROXY_SOURCE_IE 1
|
||||
#define PROXY_SOURCE_MANUAL 2
|
||||
#define PROXY_TYPE_HTTP 0
|
||||
#define PROXY_TYPE_SOCKS 1
|
||||
#define PROXY_HTTP_NO_AUTH 0
|
||||
#define PROXY_HTTP_ASK_AUTH 1
|
||||
|
||||
void ShowProxySettingsDialog();
|
||||
BOOL CALLBACK ProxySettingsDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
int CheckProxySettings(HWND hwndDlg);
|
||||
void LoadProxySettings(HWND hwndDlg);
|
||||
void SaveProxySettings(HWND hwndDlg);
|
||||
void GetProxyRegistrySettings();
|
||||
BOOL CALLBACK ProxyAuthDialogFunc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void ConstructProxyCmdLine(char *proxy_string_ptr, unsigned int size);
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,272 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
#include "registry.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
int
|
||||
GetRegistryKeys()
|
||||
{
|
||||
char windows_dir[MAX_PATH];
|
||||
char temp_path[MAX_PATH];
|
||||
char openvpn_path[MAX_PATH];
|
||||
HKEY regkey;
|
||||
|
||||
if (!GetWindowsDirectory(windows_dir, sizeof(windows_dir))) {
|
||||
/* can't get windows dir */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_GET_WINDOWS_DIR, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
/* Get path to OpenVPN installation. */
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenVPN", 0, KEY_READ, ®key)
|
||||
!= ERROR_SUCCESS)
|
||||
{
|
||||
/* registry key not found */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_REGISTRY, "");
|
||||
return(false);
|
||||
}
|
||||
if (!GetRegistryValue(regkey, "", openvpn_path, sizeof(openvpn_path)))
|
||||
{
|
||||
/* error reading registry value */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_READING_REGISTRY, "");
|
||||
return(false);
|
||||
}
|
||||
if(openvpn_path[strlen(openvpn_path) - 1] != '\\')
|
||||
strcat(openvpn_path, "\\");
|
||||
|
||||
|
||||
mysnprintf(temp_path, "%sconfig", openvpn_path);
|
||||
if (!GetRegKey("config_dir", o.config_dir,
|
||||
temp_path, sizeof(o.config_dir))) return(false);
|
||||
|
||||
if (!GetRegKey("config_ext", o.ext_string, "ovpn", sizeof(o.ext_string))) return(false);
|
||||
|
||||
mysnprintf(temp_path, "%sbin\\openvpn.exe", openvpn_path);
|
||||
if (!GetRegKey("exe_path", o.exe_path,
|
||||
temp_path, sizeof(o.exe_path))) return(false);
|
||||
|
||||
mysnprintf(temp_path, "%slog", openvpn_path);
|
||||
if (!GetRegKey("log_dir", o.log_dir,
|
||||
temp_path, sizeof(o.log_dir))) return(false);
|
||||
|
||||
if (!GetRegKey("log_append", o.append_string, "0", sizeof(o.append_string))) return(false);
|
||||
|
||||
if (!GetRegKey("priority", o.priority_string,
|
||||
"NORMAL_PRIORITY_CLASS", sizeof(o.priority_string))) return(false);
|
||||
|
||||
mysnprintf(temp_path, "%s\\notepad.exe", windows_dir);
|
||||
if (!GetRegKey("log_viewer", o.log_viewer,
|
||||
temp_path, sizeof(o.log_viewer))) return(false);
|
||||
|
||||
mysnprintf(temp_path, "%s\\notepad.exe", windows_dir);
|
||||
if (!GetRegKey("editor", o.editor,
|
||||
temp_path, sizeof(o.editor))) return(false);
|
||||
|
||||
if (!GetRegKey("allow_edit", o.allow_edit, "1", sizeof(o.allow_edit))) return(false);
|
||||
|
||||
if (!GetRegKey("allow_service", o.allow_service, "0", sizeof(o.allow_service))) return(false);
|
||||
|
||||
if (!GetRegKey("allow_password", o.allow_password, "1", sizeof(o.allow_password))) return(false);
|
||||
|
||||
if (!GetRegKey("allow_proxy", o.allow_proxy, "1", sizeof(o.allow_proxy))) return(false);
|
||||
|
||||
if (!GetRegKey("service_only", o.service_only, "0", sizeof(o.service_only))) return(false);
|
||||
|
||||
if (!GetRegKey("show_balloon", o.show_balloon, "1", sizeof(o.show_balloon))) return(false);
|
||||
|
||||
if (!GetRegKey("silent_connection", o.silent_connection, "0", sizeof(o.silent_connection))) return(false);
|
||||
|
||||
if (!GetRegKey("show_script_window", o.show_script_window, "1", sizeof(o.show_script_window))) return(false);
|
||||
|
||||
if (!GetRegKey("disconnect_on_suspend", o.disconnect_on_suspend, "1",
|
||||
sizeof(o.disconnect_on_suspend))) return(false);
|
||||
|
||||
if (!GetRegKey("passphrase_attempts", o.psw_attempts_string, "3",
|
||||
sizeof(o.psw_attempts_string))) return(false);
|
||||
o.psw_attempts = atoi(o.psw_attempts_string);
|
||||
if ((o.psw_attempts < 1) || (o.psw_attempts > 9))
|
||||
{
|
||||
/* 0 <= passphrase_attempts <= 9 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_PASSPHRASE_ATTEMPTS, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (!GetRegKey("connectscript_timeout", o.connectscript_timeout_string, "15",
|
||||
sizeof(o.connectscript_timeout_string))) return(false);
|
||||
o.connectscript_timeout = atoi(o.connectscript_timeout_string);
|
||||
if ((o.connectscript_timeout < 0) || (o.connectscript_timeout > 99))
|
||||
{
|
||||
/* 0 <= connectscript_timeout <= 99 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CONN_SCRIPT_TIMEOUT, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (!GetRegKey("disconnectscript_timeout", o.disconnectscript_timeout_string, "10",
|
||||
sizeof(o.disconnectscript_timeout_string))) return(false);
|
||||
o.disconnectscript_timeout = atoi(o.disconnectscript_timeout_string);
|
||||
if ((o.disconnectscript_timeout <= 0) || (o.disconnectscript_timeout > 99))
|
||||
{
|
||||
/* 0 < disconnectscript_timeout <= 99 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_DISCONN_SCRIPT_TIMEOUT, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (!GetRegKey("preconnectscript_timeout", o.preconnectscript_timeout_string, "10",
|
||||
sizeof(o.preconnectscript_timeout_string))) return(false);
|
||||
o.preconnectscript_timeout = atoi(o.preconnectscript_timeout_string);
|
||||
if ((o.preconnectscript_timeout <= 0) || (o.preconnectscript_timeout > 99))
|
||||
{
|
||||
/* 0 < disconnectscript_timeout <= 99 */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_PRECONN_SCRIPT_TIMEOUT, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
int GetRegKey(const char name[], char *data, const char default_data[], DWORD len)
|
||||
{
|
||||
LONG status;
|
||||
DWORD type;
|
||||
HKEY openvpn_key;
|
||||
HKEY openvpn_key_write;
|
||||
DWORD dwDispos;
|
||||
char expanded_string[MAX_PATH];
|
||||
DWORD max_len;
|
||||
|
||||
/* Save maximum string length */
|
||||
max_len=len;
|
||||
|
||||
/* If option is already set via cmd-line, return */
|
||||
if (data[0] != 0)
|
||||
{
|
||||
// Expand environment variables inside the string.
|
||||
ExpandEnvironmentStrings(data, expanded_string, sizeof(expanded_string));
|
||||
strncpy(data, expanded_string, max_len);
|
||||
return(true);
|
||||
}
|
||||
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\OpenVPN-GUI",
|
||||
0,
|
||||
KEY_READ,
|
||||
&openvpn_key);
|
||||
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
"Software\\OpenVPN-GUI",
|
||||
0,
|
||||
(LPTSTR) "",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_READ | KEY_WRITE,
|
||||
NULL,
|
||||
&openvpn_key,
|
||||
&dwDispos) != ERROR_SUCCESS)
|
||||
{
|
||||
/* error creating registry key */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CREATE_REG_KEY, "");
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* get a registry string */
|
||||
status = RegQueryValueEx(openvpn_key, name, NULL, &type, (byte *) data, &len);
|
||||
if (status != ERROR_SUCCESS || type != REG_SZ)
|
||||
{
|
||||
/* key did not exist - set default value */
|
||||
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\OpenVPN-GUI",
|
||||
0,
|
||||
KEY_READ | KEY_WRITE,
|
||||
&openvpn_key_write);
|
||||
|
||||
if (status != ERROR_SUCCESS) {
|
||||
/* can't open registry for writing */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_WRITE_REG, "");
|
||||
return(false);
|
||||
}
|
||||
if(RegSetValueEx(openvpn_key_write,
|
||||
name,
|
||||
0,
|
||||
REG_SZ,
|
||||
default_data,
|
||||
strlen(default_data)+1))
|
||||
{
|
||||
/* cant read / set reg-key */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_READ_SET_KEY, name);
|
||||
return(false);
|
||||
}
|
||||
strncpy(data, default_data, max_len);
|
||||
RegCloseKey(openvpn_key_write);
|
||||
|
||||
}
|
||||
|
||||
RegCloseKey(openvpn_key);
|
||||
|
||||
// Expand environment variables inside the string.
|
||||
ExpandEnvironmentStrings(data, expanded_string, sizeof(expanded_string));
|
||||
strncpy(data, expanded_string, max_len);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
LONG GetRegistryValue(HKEY regkey, const char *name, char *data, DWORD len)
|
||||
{
|
||||
LONG status;
|
||||
DWORD type;
|
||||
DWORD data_len;
|
||||
|
||||
data_len = len;
|
||||
|
||||
/* get a registry string */
|
||||
status = RegQueryValueEx(regkey, name, NULL, &type, (byte *) data, &data_len);
|
||||
if (status != ERROR_SUCCESS || type != REG_SZ)
|
||||
return(0);
|
||||
|
||||
return(data_len);
|
||||
|
||||
}
|
||||
|
||||
int SetRegistryValue(HKEY regkey, const char *name, char *data)
|
||||
{
|
||||
/* set a registry string */
|
||||
if(RegSetValueEx(regkey, name, 0, REG_SZ, data, strlen(data)+1) != ERROR_SUCCESS)
|
||||
{
|
||||
/* Error writing registry value */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name);
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(1);
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
int GetRegistryKeys();
|
||||
//int SetRegistryKeys();
|
||||
int GetRegKey(const char name[], char data[], const char default_data[], DWORD len);
|
||||
LONG GetRegistryValue(HKEY regkey, const char *name, char *data, DWORD len);
|
||||
int SetRegistryValue(HKEY regkey, const char *name, char *data);
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include "main.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
#include "options.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
void RunConnectScript(int config, int run_as_service)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
char batch_file[100];
|
||||
DWORD ExitCode;
|
||||
int i, TimeOut;
|
||||
TCHAR buf[1000];
|
||||
|
||||
/* Cut of extention from config filename and add "_up.bat". */
|
||||
strncpy(batch_file, o.cnn[config].config_file, sizeof(batch_file));
|
||||
batch_file[strlen(batch_file) - (strlen(o.ext_string)+1)]=0;
|
||||
strncat(batch_file, "_up.bat", sizeof(batch_file) - strlen(batch_file) - 1);
|
||||
mysnprintf(command_line, "%s\\%s", o.cnn[config].config_dir, batch_file);
|
||||
|
||||
|
||||
/* Return if no script exists */
|
||||
hFind = FindFirstFile(command_line, &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
if (!run_as_service)
|
||||
{
|
||||
/* UserInfo: Connect Script running */
|
||||
myLoadString(INFO_STATE_CONN_SCRIPT);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
}
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = 0;
|
||||
start_info.wShowWindow = SW_SHOWDEFAULT;
|
||||
start_info.hStdInput = NULL;
|
||||
start_info.hStdOutput = NULL;
|
||||
|
||||
if (!CreateProcess(NULL,
|
||||
command_line, //commandline
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
((o.show_script_window[0] == '1') ? (DWORD) CREATE_NEW_CONSOLE :
|
||||
(DWORD) CREATE_NO_WINDOW),
|
||||
NULL,
|
||||
o.cnn[config].config_dir, //start-up dir
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
/* Running Script failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_RUN_CONN_SCRIPT, command_line);
|
||||
return;
|
||||
}
|
||||
|
||||
TimeOut = o.connectscript_timeout;
|
||||
|
||||
if (TimeOut == 0)
|
||||
{
|
||||
/* Don't check exist status, just return */
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i <= TimeOut; i++)
|
||||
{
|
||||
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
|
||||
{
|
||||
/* failed to get ExitCode */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_GET_EXIT_CODE, command_line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExitCode != STILL_ACTIVE)
|
||||
{
|
||||
if (ExitCode != 0)
|
||||
{
|
||||
/* ConnectScript failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_CONN_SCRIPT_FAILED, ExitCode);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Sleep(1000);
|
||||
}
|
||||
|
||||
/* UserInfo: Timeout */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_RUN_CONN_SCRIPT_TIMEOUT, TimeOut);
|
||||
|
||||
}
|
||||
|
||||
void RunDisconnectScript(int config, int run_as_service)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
char batch_file[100];
|
||||
DWORD ExitCode;
|
||||
int i, TimeOut;
|
||||
TCHAR buf[1000];
|
||||
|
||||
/* Append "_down.bat" to config name. */
|
||||
strncpy(batch_file, o.cnn[config].config_name, sizeof(batch_file));
|
||||
strncat(batch_file, "_down.bat", sizeof(batch_file) - strlen(batch_file) - 1);
|
||||
mysnprintf(command_line, "%s\\%s", o.cnn[config].config_dir, batch_file);
|
||||
|
||||
|
||||
/* Return if no script exists */
|
||||
hFind = FindFirstFile(command_line, &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
if (!run_as_service)
|
||||
{
|
||||
/* UserInfo: Disconnect Script running */
|
||||
myLoadString(INFO_STATE_DISCONN_SCRIPT);
|
||||
SetDlgItemText(o.cnn[config].hwndStatus, TEXT_STATUS, buf);
|
||||
}
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = 0;
|
||||
start_info.wShowWindow = SW_SHOWDEFAULT;
|
||||
start_info.hStdInput = NULL;
|
||||
start_info.hStdOutput = NULL;
|
||||
|
||||
if (!CreateProcess(NULL,
|
||||
command_line, //commandline
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
((o.show_script_window[0] == '1') ? (DWORD) CREATE_NEW_CONSOLE :
|
||||
(DWORD) CREATE_NO_WINDOW),
|
||||
NULL,
|
||||
o.cnn[config].config_dir, //start-up dir
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TimeOut = o.disconnectscript_timeout;
|
||||
|
||||
for (i=0; i <= TimeOut; i++)
|
||||
{
|
||||
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExitCode != STILL_ACTIVE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void RunPreconnectScript(int config)
|
||||
{
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
char batch_file[100];
|
||||
DWORD ExitCode;
|
||||
int i, TimeOut;
|
||||
TCHAR buf[1000];
|
||||
|
||||
/* Append "_pre.bat" to config name. */
|
||||
strncpy(batch_file, o.cnn[config].config_name, sizeof(batch_file));
|
||||
strncat(batch_file, "_pre.bat", sizeof(batch_file) - strlen(batch_file) - 1);
|
||||
mysnprintf(command_line, "%s\\%s", o.cnn[config].config_dir, batch_file);
|
||||
|
||||
|
||||
/* Return if no script exists */
|
||||
hFind = FindFirstFile(command_line, &FindFileData);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FindClose(hFind);
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = 0;
|
||||
start_info.wShowWindow = SW_SHOWDEFAULT;
|
||||
start_info.hStdInput = NULL;
|
||||
start_info.hStdOutput = NULL;
|
||||
|
||||
if (!CreateProcess(NULL,
|
||||
command_line, //commandline
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
((o.show_script_window[0] == '1') ? (DWORD) CREATE_NEW_CONSOLE :
|
||||
(DWORD) CREATE_NO_WINDOW),
|
||||
NULL,
|
||||
o.cnn[config].config_dir, //start-up dir
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TimeOut = o.preconnectscript_timeout;
|
||||
|
||||
for (i=0; i <= TimeOut; i++)
|
||||
{
|
||||
if (!GetExitCodeProcess(proc_info.hProcess, &ExitCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ExitCode != STILL_ACTIVE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
void RunConnectScript(int config, int run_as_service);
|
||||
void RunDisconnectScript(int config, int run_as_service);
|
||||
void RunPreconnectScript(int config);
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include "tray.h"
|
||||
#include "service.h"
|
||||
#include "openvpn.h"
|
||||
#include "options.h"
|
||||
#include "scripts.h"
|
||||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
#include "openvpn-gui-res.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
int MyStartService()
|
||||
{
|
||||
|
||||
SC_HANDLE schSCManager;
|
||||
SC_HANDLE schService;
|
||||
SERVICE_STATUS ssStatus;
|
||||
DWORD dwOldCheckPoint;
|
||||
DWORD dwStartTickCount;
|
||||
DWORD dwWaitTime;
|
||||
char msg[200];
|
||||
TCHAR buf[1000];
|
||||
int i;
|
||||
|
||||
/* Set Service Status = Connecting */
|
||||
o.service_running = SERVICE_CONNECTING;
|
||||
SetServiceMenuStatus();
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
// Open a handle to the SC Manager database.
|
||||
schSCManager = OpenSCManager(
|
||||
NULL, // local machine
|
||||
NULL, // ServicesActive database
|
||||
SC_MANAGER_CONNECT); // Connect rights
|
||||
|
||||
if (NULL == schSCManager) {
|
||||
/* open SC manager failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_SCMGR, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
schService = OpenService(
|
||||
schSCManager, // SCM database
|
||||
"OpenVPNService", // service name
|
||||
SERVICE_START | SERVICE_QUERY_STATUS);
|
||||
|
||||
if (schService == NULL) {
|
||||
/* can't open VPN service */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_VPN_SERVICE, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Run Pre-connect script */
|
||||
for (i=0; i<o.num_configs; i++)
|
||||
RunPreconnectScript(i);
|
||||
|
||||
if (!StartService(
|
||||
schService, // handle to service
|
||||
0, // number of arguments
|
||||
NULL) ) // no arguments
|
||||
{
|
||||
/* can't start */
|
||||
ShowLocalizedMsg(NULL, ERR_START_SERVICE, "");
|
||||
goto failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("Service start pending.\n");
|
||||
}
|
||||
|
||||
// Check the status until the service is no longer start pending.
|
||||
if (!QueryServiceStatus(
|
||||
schService, // handle to service
|
||||
&ssStatus) ) // address of status information structure
|
||||
{
|
||||
/* query failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_QUERY_SERVICE, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// Save the tick count and initial checkpoint.
|
||||
dwStartTickCount = GetTickCount();
|
||||
dwOldCheckPoint = ssStatus.dwCheckPoint;
|
||||
|
||||
while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
|
||||
{
|
||||
// Do not wait longer than the wait hint. A good interval is
|
||||
// one tenth the wait hint, but no less than 1 second and no
|
||||
// more than 5 seconds.
|
||||
|
||||
dwWaitTime = ssStatus.dwWaitHint / 10;
|
||||
|
||||
if( dwWaitTime < 1000 )
|
||||
dwWaitTime = 1000;
|
||||
else if ( dwWaitTime > 5000 )
|
||||
dwWaitTime = 5000;
|
||||
|
||||
Sleep( dwWaitTime );
|
||||
|
||||
// Check the status again.
|
||||
if (!QueryServiceStatus(
|
||||
schService, // handle to service
|
||||
&ssStatus) ) // address of structure
|
||||
break;
|
||||
|
||||
if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
|
||||
{
|
||||
// The service is making progress.
|
||||
dwStartTickCount = GetTickCount();
|
||||
dwOldCheckPoint = ssStatus.dwCheckPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
|
||||
{
|
||||
// No progress made within the wait hint
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseServiceHandle(schService);
|
||||
CloseServiceHandle(schSCManager);
|
||||
|
||||
if (ssStatus.dwCurrentState != SERVICE_RUNNING)
|
||||
{
|
||||
/* service hasn't started */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_SERVICE_START_FAILED, "");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Run Connect script */
|
||||
for (i=0; i<o.num_configs; i++)
|
||||
RunConnectScript(i, true);
|
||||
|
||||
/* Set Service Status = Connected */
|
||||
o.service_running = SERVICE_CONNECTED;
|
||||
SetServiceMenuStatus();
|
||||
CheckAndSetTrayIcon();
|
||||
|
||||
/* Show "OpenVPN Service Started" Tray Balloon msg */
|
||||
myLoadString(INFO_SERVICE_STARTED);
|
||||
mysnprintf(msg," ");
|
||||
ShowTrayBalloon(buf, msg);
|
||||
|
||||
return(true);
|
||||
|
||||
failed:
|
||||
|
||||
/* Set Service Status = Disconnecting */
|
||||
o.service_running = SERVICE_DISCONNECTED;
|
||||
SetServiceMenuStatus();
|
||||
CheckAndSetTrayIcon();
|
||||
return(false);
|
||||
}
|
||||
|
||||
int MyStopService()
|
||||
{
|
||||
|
||||
SC_HANDLE schSCManager;
|
||||
SC_HANDLE schService;
|
||||
SERVICE_STATUS ssStatus;
|
||||
DWORD dwOldCheckPoint;
|
||||
DWORD dwStartTickCount;
|
||||
DWORD dwWaitTime;
|
||||
int i;
|
||||
|
||||
// Open a handle to the SC Manager database.
|
||||
schSCManager = OpenSCManager(
|
||||
NULL, // local machine
|
||||
NULL, // ServicesActive database
|
||||
SC_MANAGER_CONNECT); // Connect rights
|
||||
|
||||
if (NULL == schSCManager) {
|
||||
/* can't open SCManager */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_SCMGR, (int) GetLastError());
|
||||
return(false);
|
||||
}
|
||||
|
||||
schService = OpenService(
|
||||
schSCManager, // SCM database
|
||||
"OpenVPNService", // service name
|
||||
SERVICE_STOP);
|
||||
|
||||
if (schService == NULL) {
|
||||
/* can't open vpn service */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_VPN_SERVICE, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
/* Run DisConnect script */
|
||||
for (i=0; i<o.num_configs; i++)
|
||||
RunDisconnectScript(i, true);
|
||||
|
||||
if (!ControlService(
|
||||
schService, // handle to service
|
||||
SERVICE_CONTROL_STOP, // control value to send
|
||||
&ssStatus) ) // address of status info
|
||||
{
|
||||
/* stop failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_STOP_SERVICE, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
o.service_running = SERVICE_DISCONNECTED;
|
||||
SetServiceMenuStatus();
|
||||
CheckAndSetTrayIcon();
|
||||
return(true);
|
||||
}
|
||||
|
||||
int MyReStartService()
|
||||
{
|
||||
|
||||
MyStopService();
|
||||
Sleep(1000);
|
||||
if (MyStartService()) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
int CheckServiceStatus()
|
||||
{
|
||||
|
||||
SC_HANDLE schSCManager;
|
||||
SC_HANDLE schService;
|
||||
SERVICE_STATUS ssStatus;
|
||||
DWORD dwOldCheckPoint;
|
||||
DWORD dwStartTickCount;
|
||||
DWORD dwWaitTime;
|
||||
|
||||
// Open a handle to the SC Manager database.
|
||||
schSCManager = OpenSCManager(
|
||||
NULL, // local machine
|
||||
NULL, // ServicesActive database
|
||||
SC_MANAGER_CONNECT); // Connect rights
|
||||
|
||||
if (NULL == schSCManager) {
|
||||
o.service_running = SERVICE_NOACCESS;
|
||||
SetServiceMenuStatus();
|
||||
return(false);
|
||||
}
|
||||
|
||||
schService = OpenService(
|
||||
schSCManager, // SCM database
|
||||
"OpenVPNService", // service name
|
||||
SERVICE_QUERY_STATUS);
|
||||
|
||||
if (schService == NULL) {
|
||||
/* open vpn service failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_OPEN_VPN_SERVICE, "");
|
||||
o.service_running = SERVICE_NOACCESS;
|
||||
SetServiceMenuStatus();
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (!QueryServiceStatus(
|
||||
schService, // handle to service
|
||||
&ssStatus) ) // address of status information structure
|
||||
{
|
||||
/* query failed */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_QUERY_SERVICE, "");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if (ssStatus.dwCurrentState == SERVICE_RUNNING)
|
||||
{
|
||||
o.service_running = SERVICE_CONNECTED;
|
||||
SetServiceMenuStatus();
|
||||
SetTrayIcon(CONNECTED);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
o.service_running = SERVICE_DISCONNECTED;
|
||||
SetServiceMenuStatus();
|
||||
SetTrayIcon(DISCONNECTED);
|
||||
return(false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
int MyStartService();
|
||||
int MyStopService();
|
||||
int MyReStartService();
|
||||
int CheckServiceStatus();
|
|
@ -0,0 +1,326 @@
|
|||
#ifndef _SHELLAPI_H
|
||||
#define _SHELLAPI_H
|
||||
#if __GNUC__ >= 3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define WINSHELLAPI DECLSPEC_IMPORT
|
||||
#define ABE_LEFT 0
|
||||
#define ABE_TOP 1
|
||||
#define ABE_RIGHT 2
|
||||
#define ABE_BOTTOM 3
|
||||
#define ABS_AUTOHIDE 1
|
||||
#define ABS_ALWAYSONTOP 2
|
||||
#define SEE_MASK_CLASSNAME 1
|
||||
#define SEE_MASK_CLASSKEY 3
|
||||
#define SEE_MASK_IDLIST 4
|
||||
#define SEE_MASK_INVOKEIDLIST 12
|
||||
#define SEE_MASK_ICON 0x10
|
||||
#define SEE_MASK_HOTKEY 0x20
|
||||
#define SEE_MASK_NOCLOSEPROCESS 0x40
|
||||
#define SEE_MASK_CONNECTNETDRV 0x80
|
||||
#define SEE_MASK_FLAG_DDEWAIT 0x100
|
||||
#define SEE_MASK_DOENVSUBST 0x200
|
||||
#define SEE_MASK_FLAG_NO_UI 0x400
|
||||
#define SEE_MASK_NO_CONSOLE 0x8000
|
||||
#define SEE_MASK_UNICODE 0x10000
|
||||
#define SEE_MASK_ASYNCOK 0x100000
|
||||
#define SEE_MASK_HMONITOR 0x200000
|
||||
#define ABM_NEW 0
|
||||
#define ABM_REMOVE 1
|
||||
#define ABM_QUERYPOS 2
|
||||
#define ABM_SETPOS 3
|
||||
#define ABM_GETSTATE 4
|
||||
#define ABM_GETTASKBARPOS 5
|
||||
#define ABM_ACTIVATE 6
|
||||
#define ABM_GETAUTOHIDEBAR 7
|
||||
#define ABM_SETAUTOHIDEBAR 8
|
||||
#define ABM_WINDOWPOSCHANGED 9
|
||||
#define ABN_STATECHANGE 0
|
||||
#define ABN_POSCHANGED 1
|
||||
#define ABN_FULLSCREENAPP 2
|
||||
#define ABN_WINDOWARRANGE 3
|
||||
#define NIM_ADD 0
|
||||
#define NIM_MODIFY 1
|
||||
#define NIM_DELETE 2
|
||||
#if _WIN32_IE >= 0x0500
|
||||
#define NOTIFYICON_VERSION 3
|
||||
#define NIM_SETFOCUS 3
|
||||
#define NIM_SETVERSION 4
|
||||
#endif
|
||||
#define NIF_MESSAGE 1
|
||||
#define NIF_ICON 2
|
||||
#define NIF_TIP 4
|
||||
#define NIF_STATE 8
|
||||
#define NIS_HIDDEN 1
|
||||
#define NIS_SHAREDICON 2
|
||||
#define SE_ERR_FNF 2
|
||||
#define SE_ERR_PNF 3
|
||||
#define SE_ERR_ACCESSDENIED 5
|
||||
#define SE_ERR_OOM 8
|
||||
#define SE_ERR_DLLNOTFOUND 32
|
||||
#define SE_ERR_SHARE 26
|
||||
#define SE_ERR_ASSOCINCOMPLETE 27
|
||||
#define SE_ERR_DDETIMEOUT 28
|
||||
#define SE_ERR_DDEFAIL 29
|
||||
#define SE_ERR_DDEBUSY 30
|
||||
#define SE_ERR_NOASSOC 31
|
||||
#define FO_MOVE 1
|
||||
#define FO_COPY 2
|
||||
#define FO_DELETE 3
|
||||
#define FO_RENAME 4
|
||||
#define FOF_MULTIDESTFILES 1
|
||||
#define FOF_CONFIRMMOUSE 2
|
||||
#define FOF_SILENT 4
|
||||
#define FOF_RENAMEONCOLLISION 8
|
||||
#define FOF_NOCONFIRMATION 16
|
||||
#define FOF_WANTMAPPINGHANDLE 32
|
||||
#define FOF_ALLOWUNDO 64
|
||||
#define FOF_FILESONLY 128
|
||||
#define FOF_SIMPLEPROGRESS 256
|
||||
#define FOF_NOCONFIRMMKDIR 512
|
||||
#define FOF_NOERRORUI 1024
|
||||
#define FOF_NOCOPYSECURITYATTRIBS 2048
|
||||
#define PO_DELETE 19
|
||||
#define PO_RENAME 20
|
||||
#define PO_PORTCHANGE 32
|
||||
#define PO_REN_PORT 52
|
||||
#define SHGFI_ICON 256
|
||||
#define SHGFI_DISPLAYNAME 512
|
||||
#define SHGFI_TYPENAME 1024
|
||||
#define SHGFI_ATTRIBUTES 2048
|
||||
#define SHGFI_ICONLOCATION 4096
|
||||
#define SHGFI_EXETYPE 8192
|
||||
#define SHGFI_SYSICONINDEX 16384
|
||||
#define SHGFI_LINKOVERLAY 32768
|
||||
#define SHGFI_SELECTED 65536
|
||||
#define SHGFI_ATTR_SPECIFIED 131072
|
||||
#define SHGFI_LARGEICON 0
|
||||
#define SHGFI_SMALLICON 1
|
||||
#define SHGFI_OPENICON 2
|
||||
#define SHGFI_SHELLICONSIZE 4
|
||||
#define SHGFI_PIDL 8
|
||||
#define SHGFI_USEFILEATTRIBUTES 16
|
||||
#define SHERB_NOCONFIRMATION 1
|
||||
#define SHERB_NOPROGRESSUI 2
|
||||
#define SHERB_NOSOUND 4
|
||||
|
||||
typedef WORD FILEOP_FLAGS;
|
||||
typedef WORD PRINTEROP_FLAGS;
|
||||
#include <pshpack2.h>
|
||||
typedef struct _AppBarData {
|
||||
DWORD cbSize;
|
||||
HWND hWnd;
|
||||
UINT uCallbackMessage;
|
||||
UINT uEdge;
|
||||
RECT rc;
|
||||
LPARAM lParam;
|
||||
} APPBARDATA,*PAPPBARDATA;
|
||||
DECLARE_HANDLE(HDROP);
|
||||
|
||||
typedef struct _NOTIFYICONDATAA {
|
||||
DWORD cbSize;
|
||||
HWND hWnd;
|
||||
UINT uID;
|
||||
UINT uFlags;
|
||||
UINT uCallbackMessage;
|
||||
HICON hIcon;
|
||||
#if _WIN32_IE >= 0x0500
|
||||
CHAR szTip[128];
|
||||
DWORD dwState;
|
||||
DWORD dwStateMask;
|
||||
CHAR szInfo[256];
|
||||
_ANONYMOUS_UNION union {
|
||||
UINT uTimeout;
|
||||
UINT uVersion;
|
||||
} DUMMYUNIONNAME;
|
||||
CHAR szInfoTitle[64];
|
||||
DWORD dwInfoFlags;
|
||||
#else
|
||||
CHAR szTip[64];
|
||||
#endif
|
||||
#if _WIN32_IE >= 0x600
|
||||
GUID guidItem;
|
||||
#endif
|
||||
} NOTIFYICONDATAA,*PNOTIFYICONDATAA;
|
||||
|
||||
typedef struct _NOTIFYICONDATAW {
|
||||
DWORD cbSize;
|
||||
HWND hWnd;
|
||||
UINT uID;
|
||||
UINT uFlags;
|
||||
UINT uCallbackMessage;
|
||||
HICON hIcon;
|
||||
#if _WIN32_IE >= 0x0500
|
||||
WCHAR szTip[128];
|
||||
DWORD dwState;
|
||||
DWORD dwStateMask;
|
||||
WCHAR szInfo[256];
|
||||
_ANONYMOUS_UNION union {
|
||||
UINT uTimeout;
|
||||
UINT uVersion;
|
||||
} DUMMYUNIONNAME;
|
||||
WCHAR szInfoTitle[64];
|
||||
DWORD dwInfoFlags;
|
||||
#else
|
||||
WCHAR szTip[64];
|
||||
#endif
|
||||
#if _WIN32_IE >= 0x600
|
||||
GUID guidItem;
|
||||
#endif
|
||||
} NOTIFYICONDATAW,*PNOTIFYICONDATAW;
|
||||
|
||||
typedef struct _SHELLEXECUTEINFOA {
|
||||
DWORD cbSize;
|
||||
ULONG fMask;
|
||||
HWND hwnd;
|
||||
LPCSTR lpVerb;
|
||||
LPCSTR lpFile;
|
||||
LPCSTR lpParameters;
|
||||
LPCSTR lpDirectory;
|
||||
int nShow;
|
||||
HINSTANCE hInstApp;
|
||||
PVOID lpIDList;
|
||||
LPCSTR lpClass;
|
||||
HKEY hkeyClass;
|
||||
DWORD dwHotKey;
|
||||
HANDLE hIcon;
|
||||
HANDLE hProcess;
|
||||
} SHELLEXECUTEINFOA,*LPSHELLEXECUTEINFOA;
|
||||
typedef struct _SHELLEXECUTEINFOW {
|
||||
DWORD cbSize;
|
||||
ULONG fMask;
|
||||
HWND hwnd;
|
||||
LPCWSTR lpVerb;
|
||||
LPCWSTR lpFile;
|
||||
LPCWSTR lpParameters;
|
||||
LPCWSTR lpDirectory;
|
||||
int nShow;
|
||||
HINSTANCE hInstApp;
|
||||
PVOID lpIDList;
|
||||
LPCWSTR lpClass;
|
||||
HKEY hkeyClass;
|
||||
DWORD dwHotKey;
|
||||
HANDLE hIcon;
|
||||
HANDLE hProcess;
|
||||
} SHELLEXECUTEINFOW,*LPSHELLEXECUTEINFOW;
|
||||
typedef struct _SHFILEOPSTRUCTA {
|
||||
HWND hwnd;
|
||||
UINT wFunc;
|
||||
LPCSTR pFrom;
|
||||
LPCSTR pTo;
|
||||
FILEOP_FLAGS fFlags;
|
||||
BOOL fAnyOperationsAborted;
|
||||
PVOID hNameMappings;
|
||||
LPCSTR lpszProgressTitle;
|
||||
} SHFILEOPSTRUCTA,*LPSHFILEOPSTRUCTA;
|
||||
typedef struct _SHFILEOPSTRUCTW {
|
||||
HWND hwnd;
|
||||
UINT wFunc;
|
||||
LPCWSTR pFrom;
|
||||
LPCWSTR pTo;
|
||||
FILEOP_FLAGS fFlags;
|
||||
BOOL fAnyOperationsAborted;
|
||||
PVOID hNameMappings;
|
||||
LPCWSTR lpszProgressTitle;
|
||||
} SHFILEOPSTRUCTW,*LPSHFILEOPSTRUCTW;
|
||||
typedef struct _SHFILEINFOA {
|
||||
HICON hIcon;
|
||||
int iIcon;
|
||||
DWORD dwAttributes;
|
||||
CHAR szDisplayName[MAX_PATH];
|
||||
CHAR szTypeName[80];
|
||||
} SHFILEINFOA;
|
||||
typedef struct _SHFILEINFOW {
|
||||
HICON hIcon;
|
||||
int iIcon;
|
||||
DWORD dwAttributes;
|
||||
WCHAR szDisplayName[MAX_PATH];
|
||||
WCHAR szTypeName[80];
|
||||
} SHFILEINFOW;
|
||||
typedef struct _SHQUERYRBINFO {
|
||||
DWORD cbSize;
|
||||
__int64 i64Size;
|
||||
__int64 i64NumItems;
|
||||
} SHQUERYRBINFO, *LPSHQUERYRBINFO;
|
||||
#include <poppack.h>
|
||||
|
||||
LPWSTR * WINAPI CommandLineToArgvW(LPCWSTR,int*);
|
||||
void WINAPI DragAcceptFiles(HWND,BOOL);
|
||||
void WINAPI DragFinish(HDROP);
|
||||
UINT WINAPI DragQueryFileA(HDROP,UINT,LPSTR,UINT);
|
||||
UINT WINAPI DragQueryFileW(HDROP,UINT,LPWSTR,UINT);
|
||||
BOOL WINAPI DragQueryPoint(HDROP,LPPOINT);
|
||||
HICON WINAPI DuplicateIcon(HINSTANCE,HICON);
|
||||
HICON WINAPI ExtractAssociatedIconA(HINSTANCE,LPCSTR,PWORD);
|
||||
HICON WINAPI ExtractAssociatedIconW(HINSTANCE,LPCWSTR,PWORD);
|
||||
HICON WINAPI ExtractIconA(HINSTANCE,LPCSTR,UINT);
|
||||
HICON WINAPI ExtractIconW(HINSTANCE,LPCWSTR,UINT);
|
||||
UINT WINAPI ExtractIconExA(LPCSTR,int,HICON*,HICON*,UINT);
|
||||
UINT WINAPI ExtractIconExW(LPCWSTR,int,HICON*,HICON*,UINT);
|
||||
HINSTANCE WINAPI FindExecutableA(LPCSTR,LPCSTR,LPSTR);
|
||||
HINSTANCE WINAPI FindExecutableW(LPCWSTR,LPCWSTR,LPWSTR);
|
||||
UINT WINAPI SHAppBarMessage(DWORD,PAPPBARDATA);
|
||||
BOOL WINAPI Shell_NotifyIconA(DWORD,PNOTIFYICONDATAA);
|
||||
BOOL WINAPI Shell_NotifyIconW(DWORD,PNOTIFYICONDATAW);
|
||||
int WINAPI ShellAboutA(HWND,LPCSTR,LPCSTR,HICON);
|
||||
int WINAPI ShellAboutW(HWND,LPCWSTR,LPCWSTR,HICON);
|
||||
HINSTANCE WINAPI ShellExecuteA(HWND,LPCSTR,LPCSTR,LPCSTR,LPCSTR,INT);
|
||||
HINSTANCE WINAPI ShellExecuteW(HWND,LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR,INT);
|
||||
BOOL WINAPI ShellExecuteExA(LPSHELLEXECUTEINFOA);
|
||||
BOOL WINAPI ShellExecuteExW(LPSHELLEXECUTEINFOW);
|
||||
int WINAPI SHFileOperationA(LPSHFILEOPSTRUCTA);
|
||||
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW);
|
||||
void WINAPI SHFreeNameMappings(HANDLE);
|
||||
DWORD WINAPI SHGetFileInfoA(LPCSTR,DWORD,SHFILEINFOA*,UINT,UINT);
|
||||
DWORD WINAPI SHGetFileInfoW(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
|
||||
HRESULT WINAPI SHQueryRecycleBinA(LPCSTR, LPSHQUERYRBINFO);
|
||||
HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR, LPSHQUERYRBINFO);
|
||||
HRESULT WINAPI SHEmptyRecycleBinA(HWND,LPCSTR,DWORD);
|
||||
HRESULT WINAPI SHEmptyRecycleBinW(HWND,LPCWSTR,DWORD);
|
||||
|
||||
#ifdef UNICODE
|
||||
typedef NOTIFYICONDATAW NOTIFYICONDATA,*PNOTIFYICONDATA;
|
||||
typedef SHELLEXECUTEINFOW SHELLEXECUTEINFO,*LPSHELLEXECUTEINFO;
|
||||
typedef SHFILEOPSTRUCTW SHFILEOPSTRUCT,*LPSHFILEOPSTRUCT;
|
||||
typedef SHFILEINFOW SHFILEINFO;
|
||||
#define DragQueryFile DragQueryFileW
|
||||
#define ExtractAssociatedIcon ExtractAssociatedIconW
|
||||
#define ExtractIcon ExtractIconW
|
||||
#define ExtractIconEx ExtractIconExW
|
||||
#define FindExecutable FindExecutableW
|
||||
#define Shell_NotifyIcon Shell_NotifyIconW
|
||||
#define ShellAbout ShellAboutW
|
||||
#define ShellExecute ShellExecuteW
|
||||
#define ShellExecuteEx ShellExecuteExW
|
||||
#define SHFileOperation SHFileOperationW
|
||||
#define SHGetFileInfo SHGetFileInfoW
|
||||
#define SHQueryRecycleBin SHQueryRecycleBinW
|
||||
#define SHEmptyRecycleBin SHEmptyRecycleBinW
|
||||
|
||||
#else
|
||||
typedef NOTIFYICONDATAA NOTIFYICONDATA,*PNOTIFYICONDATA;
|
||||
typedef SHELLEXECUTEINFOA SHELLEXECUTEINFO,*LPSHELLEXECUTEINFO;
|
||||
typedef SHFILEOPSTRUCTA SHFILEOPSTRUCT,*LPSHFILEOPSTRUCT;
|
||||
typedef SHFILEINFOA SHFILEINFO;
|
||||
#define DragQueryFile DragQueryFileA
|
||||
#define ExtractAssociatedIcon ExtractAssociatedIconA
|
||||
#define ExtractIcon ExtractIconA
|
||||
#define ExtractIconEx ExtractIconExA
|
||||
#define FindExecutable FindExecutableA
|
||||
#define Shell_NotifyIcon Shell_NotifyIconA
|
||||
#define ShellAbout ShellAboutA
|
||||
#define ShellExecute ShellExecuteA
|
||||
#define ShellExecuteEx ShellExecuteExA
|
||||
#define SHFileOperation SHFileOperationA
|
||||
#define SHGetFileInfo SHGetFileInfoA
|
||||
#define SHQueryRecycleBin SHQueryRecycleBinA
|
||||
#define SHEmptyRecycleBin SHEmptyRecycleBinA
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,591 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
#define _WIN32_IE 0x0500
|
||||
#define NIF_INFO 0x00000010
|
||||
// Notify Icon Infotip flags
|
||||
#define NIIF_NONE 0x00000000
|
||||
// icon flags are mutually exclusive
|
||||
// and take only the lowest 2 bits
|
||||
#define NIIF_INFO 0x00000001
|
||||
#define NIIF_WARNING 0x00000002
|
||||
#define NIIF_ERROR 0x00000003
|
||||
#define NIIF_ICON_MASK 0x0000000F
|
||||
|
||||
#include <windows.h>
|
||||
#include <time.h>
|
||||
#include "tray.h"
|
||||
#include "service.h"
|
||||
#include "shellapi.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "openvpn.h"
|
||||
#include "openvpn_config.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
|
||||
//POPUP MENU
|
||||
HMENU hMenu;
|
||||
HMENU hMenuConn[MAX_CONFIGS];
|
||||
HMENU hMenuService;
|
||||
|
||||
NOTIFYICONDATA ni;
|
||||
extern struct options o;
|
||||
|
||||
// Mouse clicks on tray
|
||||
void OnNotifyTray(LPARAM lParam)
|
||||
{
|
||||
POINT pt; // point structure
|
||||
int connected_config;
|
||||
int i;
|
||||
TCHAR buf[1000];
|
||||
|
||||
// Right click, show the menu
|
||||
switch(lParam) {
|
||||
case WM_RBUTTONDOWN:
|
||||
/* Re-read configs and re-create menus if no connection is running */
|
||||
if (CountConnectedState(DISCONNECTED) == o.num_configs)
|
||||
{
|
||||
DestroyPopupMenus();
|
||||
BuildFileList();
|
||||
CreatePopupMenus();
|
||||
}
|
||||
|
||||
GetCursorPos(&pt); // get the cursors position
|
||||
SetForegroundWindow(o.hWnd); // set the foreground window
|
||||
TrackPopupMenu(hMenu,TPM_RIGHTALIGN,pt.x,pt.y,0,o.hWnd,NULL);// track the popup
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
if (o.service_only[0]=='1')
|
||||
{
|
||||
/* Start OpenVPN Service */
|
||||
if (o.service_running == SERVICE_DISCONNECTED)
|
||||
{
|
||||
MyStartService();
|
||||
}
|
||||
else if (o.service_running == SERVICE_CONNECTED)
|
||||
{
|
||||
/* Stop OpenVPN service */
|
||||
myLoadString(IDM_TEXT_ASK_STOP_SERVICE);
|
||||
if (MessageBox(NULL, buf, GUI_NAME, MB_YESNO | MB_SETFOREGROUND) == IDYES)
|
||||
{
|
||||
MyStopService();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Open Status window if only one connection is running */
|
||||
connected_config = -1;
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if(o.cnn[i].connect_status != DISCONNECTED)
|
||||
{
|
||||
if (connected_config == -1)
|
||||
{
|
||||
connected_config = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
connected_config = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connected_config != -1)
|
||||
{
|
||||
ShowWindow(o.cnn[connected_config].hwndStatus, SW_SHOW);
|
||||
SetForegroundWindow(o.cnn[connected_config].hwndStatus);
|
||||
}
|
||||
|
||||
/* Re-read configs and re-create menus if no connection is running */
|
||||
if (CountConnectedState(DISCONNECTED) == o.num_configs)
|
||||
{
|
||||
DestroyPopupMenus();
|
||||
BuildFileList();
|
||||
CreatePopupMenus();
|
||||
|
||||
/* Start connection if only one config exist */
|
||||
if ((o.num_configs == 1) && (o.cnn[0].connect_status == DISCONNECTED))
|
||||
StartOpenVPN(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
PostMessage(o.hWnd,WM_NULL,0,0);// post a null message
|
||||
}
|
||||
|
||||
|
||||
void OnDestroyTray()
|
||||
{
|
||||
//Destroy popup menu
|
||||
DestroyMenu(hMenu);
|
||||
|
||||
//Remove Icon from Tray
|
||||
Shell_NotifyIcon(NIM_DELETE, &ni);
|
||||
}
|
||||
|
||||
|
||||
/* Create Popup Menus */
|
||||
void CreatePopupMenus()
|
||||
{
|
||||
int i;
|
||||
//extern struct options o;
|
||||
|
||||
/* Create Main menu */
|
||||
hMenu=CreatePopupMenu();
|
||||
|
||||
/* Create a menu for every config */
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
hMenuConn[i]=CreatePopupMenu();
|
||||
|
||||
/* Create the Service Menu */
|
||||
hMenuService=CreatePopupMenu();
|
||||
|
||||
/* Put something on the menus */
|
||||
CreateItemList(hMenu);
|
||||
}
|
||||
|
||||
/* Destroy Popup Menus */
|
||||
void DestroyPopupMenus()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Destroy Main menu */
|
||||
DestroyMenu(hMenu);
|
||||
|
||||
/* Destroy all config submenus */
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
DestroyMenu(hMenuConn[i]);
|
||||
|
||||
/* Destroy the Service Menu */
|
||||
DestroyMenu(hMenuService);
|
||||
|
||||
}
|
||||
|
||||
void CreateItemList()
|
||||
{
|
||||
extern char ext_string[];
|
||||
extern char allow_edit[2];
|
||||
extern char allow_service[2];
|
||||
int i;
|
||||
TCHAR buf[1000];
|
||||
|
||||
if (o.num_configs == 1)
|
||||
{
|
||||
/* Create Main menu with actions */
|
||||
if (o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_CONNECT);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_CONNECTMENU, buf);
|
||||
myLoadString(IDM_TEXT_DISCONNECT);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_DISCONNECTMENU, buf);
|
||||
myLoadString(IDM_TEXT_STATUS);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_STATUSMENU, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
myLoadString(IDM_TEXT_SERVICEONLY_START);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_START, buf);
|
||||
myLoadString(IDM_TEXT_SERVICEONLY_STOP);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_STOP, buf);
|
||||
myLoadString(IDM_TEXT_SERVICEONLY_RESTART);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_RESTART, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
|
||||
myLoadString(IDM_TEXT_VIEWLOG);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_VIEWLOGMENU, buf);
|
||||
if (o.allow_edit[0]=='1')
|
||||
{
|
||||
myLoadString(IDM_TEXT_EDITCONFIG);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_EDITMENU, buf);
|
||||
}
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
if (o.allow_password[0]=='1')
|
||||
{
|
||||
myLoadString(IDM_TEXT_PASSPHRASE);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_PASSPHRASEMENU, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
if (o.allow_service[0]=='1' && o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_SERVICE);
|
||||
AppendMenu(hMenu,MF_POPUP,(UINT) hMenuService, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
if (o.allow_proxy[0]=='1' && o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_PROXY);
|
||||
AppendMenu(hMenu,MF_STRING ,IDM_PROXY, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
myLoadString(IDM_TEXT_ABOUT);
|
||||
AppendMenu(hMenu,MF_STRING ,IDM_ABOUT, buf);
|
||||
myLoadString(IDM_TEXT_CLOSE);
|
||||
AppendMenu(hMenu,MF_STRING ,IDM_CLOSE, buf);
|
||||
|
||||
SetMenuStatus(0, DISCONNECTED);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create Main menu with all connections */
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
AppendMenu(hMenu,MF_POPUP,(UINT) hMenuConn[i],o.cnn[i].config_name);
|
||||
if (o.num_configs > 0)
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
if (o.allow_service[0]=='1' && o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_SERVICE);
|
||||
AppendMenu(hMenu,MF_POPUP,(UINT) hMenuService, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
if (o.service_only[0]=='1')
|
||||
{
|
||||
myLoadString(IDM_TEXT_SERVICEONLY_START);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_START, buf);
|
||||
myLoadString(IDM_TEXT_SERVICEONLY_STOP);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_STOP, buf);
|
||||
myLoadString(IDM_TEXT_SERVICEONLY_RESTART);
|
||||
AppendMenu(hMenu,MF_STRING, IDM_SERVICE_RESTART, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
if (o.allow_proxy[0]=='1' && o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_PROXY);
|
||||
AppendMenu(hMenu,MF_STRING ,IDM_PROXY, buf);
|
||||
AppendMenu(hMenu,MF_SEPARATOR,0,0);
|
||||
}
|
||||
myLoadString(IDM_TEXT_ABOUT);
|
||||
AppendMenu(hMenu,MF_STRING ,IDM_ABOUT, buf);
|
||||
myLoadString(IDM_TEXT_CLOSE);
|
||||
AppendMenu(hMenu,MF_STRING ,IDM_CLOSE, buf);
|
||||
|
||||
|
||||
/* Create PopUp menus for every connection */
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if (o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_CONNECT);
|
||||
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_CONNECTMENU+i, buf);
|
||||
myLoadString(IDM_TEXT_DISCONNECT);
|
||||
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_DISCONNECTMENU+i, buf);
|
||||
myLoadString(IDM_TEXT_STATUS);
|
||||
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_STATUSMENU+i, buf);
|
||||
AppendMenu(hMenuConn[i],MF_SEPARATOR,0,0);
|
||||
}
|
||||
myLoadString(IDM_TEXT_VIEWLOG);
|
||||
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_VIEWLOGMENU+i, buf);
|
||||
if (o.allow_edit[0]=='1') {
|
||||
myLoadString(IDM_TEXT_EDITCONFIG);
|
||||
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_EDITMENU+i, buf);
|
||||
}
|
||||
#ifndef DISABLE_CHANGE_PASSWORD
|
||||
if (o.allow_password[0]=='1')
|
||||
{
|
||||
myLoadString(IDM_TEXT_PASSPHRASE);
|
||||
AppendMenu(hMenuConn[i],MF_STRING, (UINT_PTR)IDM_PASSPHRASEMENU+i, buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
SetMenuStatus(i, DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create Service menu */
|
||||
if (o.allow_service[0]=='1' && o.service_only[0]=='0')
|
||||
{
|
||||
myLoadString(IDM_TEXT_SERVICE_START);
|
||||
AppendMenu(hMenuService,MF_STRING, IDM_SERVICE_START, buf);
|
||||
myLoadString(IDM_TEXT_SERVICE_STOP);
|
||||
AppendMenu(hMenuService,MF_STRING, IDM_SERVICE_STOP, buf);
|
||||
myLoadString(IDM_TEXT_SERVICE_RESTART);
|
||||
AppendMenu(hMenuService,MF_STRING, IDM_SERVICE_RESTART, buf);
|
||||
}
|
||||
|
||||
SetServiceMenuStatus();
|
||||
}
|
||||
|
||||
|
||||
BOOL LoadAppIcon()
|
||||
{
|
||||
|
||||
// Load icon from resource
|
||||
HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(APP_ICON),
|
||||
IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
|
||||
if (hIcon) {
|
||||
SendMessage(o.hWnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon));
|
||||
SendMessage(o.hWnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); //ALT+TAB icon
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void ShowTrayIcon()
|
||||
{
|
||||
TCHAR buf[1000];
|
||||
|
||||
ni.cbSize = sizeof(ni);
|
||||
ni.uID = 0;
|
||||
myLoadString(MSG_TIP);
|
||||
lstrcpyn(ni.szTip, buf, sizeof(ni.szTip));
|
||||
ni.hWnd = o.hWnd;
|
||||
ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; // We want to use icon, tip, and callback message
|
||||
ni.uCallbackMessage = WM_NOTIFYICONTRAY; // Our custom callback message (WM_APP + 1)
|
||||
|
||||
|
||||
//Load selected icon
|
||||
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_DISCONNECTED));
|
||||
|
||||
Shell_NotifyIcon(NIM_ADD, &ni);
|
||||
|
||||
}
|
||||
|
||||
/* SetTrayIcon(int connected)
|
||||
* connected=0 -> DisConnected
|
||||
* connected=1 -> Connecting
|
||||
* connected=2 -> Connected
|
||||
*/
|
||||
void SetTrayIcon(int connected)
|
||||
{
|
||||
char msg[500];
|
||||
char msg_connected[100];
|
||||
char msg_connecting[100];
|
||||
char conn_name[200];
|
||||
char connected_since[50];
|
||||
int i, first_conn;
|
||||
int config=0;
|
||||
TCHAR buf[1000];
|
||||
|
||||
ni.cbSize = sizeof(ni);
|
||||
ni.uID = 0;
|
||||
ni.hWnd = o.hWnd;
|
||||
ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; // We want to use icon, tip, and callback message
|
||||
ni.uCallbackMessage = WM_NOTIFYICONTRAY; // Our custom callback message (WM_APP + 1)
|
||||
|
||||
myLoadString(MSG_TIP);
|
||||
strncpy(msg, buf, sizeof(ni.szTip));
|
||||
|
||||
myLoadString(MSG_TIP_CONNECTED);
|
||||
strncpy(msg_connected, buf, sizeof(msg_connected));
|
||||
|
||||
myLoadString(MSG_TIP_CONNECTING);
|
||||
strncpy(msg_connecting, buf, sizeof(msg_connecting));
|
||||
|
||||
first_conn=1;
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if(o.cnn[i].connect_status == CONNECTED)
|
||||
{
|
||||
/* Append connection name to Icon Tip Msg */
|
||||
if (first_conn)
|
||||
strncat(msg, msg_connected, sizeof(msg) - strlen(msg) - 1);
|
||||
else
|
||||
strncat(msg, ", ", sizeof(msg) - strlen(msg) - 1);
|
||||
strncat(msg, o.cnn[i].config_name, sizeof(msg) - strlen(msg) - 1);
|
||||
first_conn=0;
|
||||
config=i;
|
||||
}
|
||||
}
|
||||
|
||||
first_conn=1;
|
||||
for (i=0; i < o.num_configs; i++)
|
||||
{
|
||||
if((o.cnn[i].connect_status == CONNECTING) ||
|
||||
(o.cnn[i].connect_status == RECONNECTING))
|
||||
{
|
||||
/* Append connection name to Icon Tip Msg */
|
||||
if (first_conn)
|
||||
strncat(msg, msg_connecting, sizeof(msg) - strlen(msg) - 1);
|
||||
else
|
||||
strncat(msg, ", ", sizeof(msg) - strlen(msg) - 1);
|
||||
strncat(msg, o.cnn[i].config_name, sizeof(msg) - strlen(msg) - 1);
|
||||
first_conn=0;
|
||||
}
|
||||
}
|
||||
|
||||
if (CountConnectedState(CONNECTED) == 1)
|
||||
{
|
||||
/* Append "Connected Since and Assigned IP msg" */
|
||||
time_t con_time;
|
||||
con_time=time(NULL);
|
||||
strftime(connected_since, sizeof(connected_since), "%b %d, %H:%M",
|
||||
localtime(&o.cnn[config].connected_since));
|
||||
myLoadString(MSG_TIP_CONNECTED_SINCE);
|
||||
strncat(msg, buf, sizeof(msg) - strlen(msg) - 1);
|
||||
strncat(msg, connected_since, sizeof(msg) - strlen(msg) - 1);
|
||||
if (strlen(o.cnn[config].ip) > 0)
|
||||
{
|
||||
char assigned_ip[100];
|
||||
myLoadString(MSG_TIP_ASSIGNED_IP);
|
||||
mysnprintf(assigned_ip, buf, o.cnn[config].ip);
|
||||
strncat(msg, assigned_ip, sizeof(msg) - strlen(msg) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(ni.szTip, msg, sizeof(ni.szTip));
|
||||
|
||||
//Load selected icon
|
||||
if (connected==2)
|
||||
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_CONNECTED));
|
||||
else if (connected==1)
|
||||
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_CONNECTING));
|
||||
else if (connected==0)
|
||||
ni.hIcon = (HICON)LoadIcon(o.hInstance, MAKEINTRESOURCE(APP_ICON_DISCONNECTED));
|
||||
|
||||
Shell_NotifyIcon(NIM_MODIFY, &ni);
|
||||
}
|
||||
|
||||
void ShowTrayBalloon(char *infotitle_msg, char *info_msg)
|
||||
{
|
||||
ni.cbSize = sizeof(ni);
|
||||
ni.uID = 0;
|
||||
ni.hWnd = o.hWnd;
|
||||
ni.uFlags = NIF_INFO; /* We want to show a balloon */
|
||||
ni.uTimeout = 5000;
|
||||
ni.dwInfoFlags = NIIF_INFO; /* Show an Info Icon */
|
||||
strncpy(ni.szInfo, info_msg, sizeof(ni.szInfo));
|
||||
strncpy(ni.szInfoTitle, infotitle_msg, sizeof(ni.szInfoTitle));
|
||||
|
||||
Shell_NotifyIcon(NIM_MODIFY, &ni);
|
||||
}
|
||||
|
||||
|
||||
void SetMenuStatus (int config, int bCheck)
|
||||
{
|
||||
/* bCheck values:
|
||||
* 0 - Not Connected
|
||||
* 1 - Connecting
|
||||
* 2 - Connected
|
||||
* 4 - Disconnecting
|
||||
*/
|
||||
|
||||
|
||||
unsigned int iState;
|
||||
|
||||
if (o.num_configs == 1)
|
||||
{
|
||||
if (bCheck == DISCONNECTED)
|
||||
{
|
||||
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_ENABLED);
|
||||
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
|
||||
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_GRAYED);
|
||||
}
|
||||
if (bCheck == CONNECTING)
|
||||
{
|
||||
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
|
||||
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_ENABLED);
|
||||
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
|
||||
}
|
||||
if (bCheck == CONNECTED)
|
||||
{
|
||||
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
|
||||
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_ENABLED);
|
||||
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
|
||||
}
|
||||
if (bCheck == DISCONNECTING)
|
||||
{
|
||||
EnableMenuItem(hMenu, IDM_CONNECTMENU, MF_GRAYED);
|
||||
EnableMenuItem(hMenu, IDM_DISCONNECTMENU, MF_GRAYED);
|
||||
EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iState = ((bCheck == CONNECTED) || (bCheck == DISCONNECTING)) ?
|
||||
MF_CHECKED : MF_UNCHECKED ;
|
||||
CheckMenuItem (hMenu, (UINT) hMenuConn[config], iState) ;
|
||||
|
||||
if (bCheck == DISCONNECTED)
|
||||
{
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_CONNECTMENU + config, MF_ENABLED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_DISCONNECTMENU + config, MF_GRAYED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_STATUSMENU + config, MF_GRAYED);
|
||||
}
|
||||
if (bCheck == CONNECTING)
|
||||
{
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_CONNECTMENU + config, MF_GRAYED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_DISCONNECTMENU + config, MF_ENABLED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_STATUSMENU + config, MF_ENABLED);
|
||||
}
|
||||
if (bCheck == CONNECTED)
|
||||
{
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_CONNECTMENU + config, MF_GRAYED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_DISCONNECTMENU + config, MF_ENABLED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_STATUSMENU + config, MF_ENABLED);
|
||||
}
|
||||
if (bCheck == DISCONNECTING)
|
||||
{
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_CONNECTMENU + config, MF_GRAYED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_DISCONNECTMENU + config, MF_GRAYED);
|
||||
EnableMenuItem(hMenuConn[config], (UINT_PTR)IDM_STATUSMENU + config, MF_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetServiceMenuStatus()
|
||||
{
|
||||
HMENU hMenuHandle;
|
||||
|
||||
if (o.allow_service[0]=='0' && o.service_only[0]=='0')
|
||||
return;
|
||||
|
||||
if (o.service_only[0]=='1')
|
||||
hMenuHandle = hMenu;
|
||||
else
|
||||
hMenuHandle = hMenuService;
|
||||
|
||||
|
||||
if ((o.service_running == SERVICE_NOACCESS) ||
|
||||
(o.service_running == SERVICE_CONNECTING))
|
||||
{
|
||||
/* Service is disabled */
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_START, MF_GRAYED);
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_STOP, MF_GRAYED);
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_RESTART, MF_GRAYED);
|
||||
}
|
||||
else if (o.service_running == SERVICE_CONNECTED)
|
||||
{
|
||||
/* Service is running */
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_START, MF_GRAYED);
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_STOP, MF_ENABLED);
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_RESTART, MF_ENABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Service is not running */
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_START, MF_ENABLED);
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_STOP, MF_GRAYED);
|
||||
EnableMenuItem(hMenuHandle, IDM_SERVICE_RESTART, MF_GRAYED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
#define WM_NOTIFYICONTRAY (WM_APP + 1)
|
||||
|
||||
//Popup Menu items
|
||||
|
||||
#define IDM_PROXY 221
|
||||
#define IDM_ABOUT 222
|
||||
|
||||
#define IDM_CLOSE 223
|
||||
|
||||
#define IDM_TEXT_CONN1 "Office"
|
||||
#define IDM_CONN1 301
|
||||
#define IDM_TEXT_CONN2 "Home"
|
||||
#define IDM_CONN2 302
|
||||
|
||||
#define IDM_CONNECTMENU 300
|
||||
#define IDM_DISCONNECTMENU 400
|
||||
#define IDM_STATUSMENU 500
|
||||
#define IDM_VIEWLOGMENU 600
|
||||
#define IDM_EDITMENU 700
|
||||
#define IDM_PASSPHRASEMENU 800
|
||||
|
||||
/* Service submenu */
|
||||
#define IDM_SERVICEMENU 900
|
||||
#define IDM_SERVICE_START 901
|
||||
#define IDM_SERVICE_STOP 902
|
||||
#define IDM_SERVICE_RESTART 903
|
||||
|
||||
|
||||
void CreatePopupMenus(); //Create popup menus
|
||||
void DestroyPopupMenus(); //Destroy popup menus
|
||||
void OnNotifyTray(LPARAM lParam); //Tray message (mouse clicks on tray icon)
|
||||
void OnDestroyTray(void); //WM_DESTROY message
|
||||
void ShowTrayIcon(); //Put app icon in systray
|
||||
void SetTrayIcon(int connected); //Change systray icon
|
||||
BOOL LoadAppIcon(); //Application icon
|
||||
void CreateItemList(); //Crate Popup menu
|
||||
void SetMenuStatus (int config, int bCheck); //Mark connection as connected/disconnected
|
||||
void SetServiceMenuStatus(); //Diabled Service menu items.
|
||||
void ShowTrayBalloon(char *infotitle_msg, char *info_msg);
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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 <windows.h>
|
||||
#include "tray.h"
|
||||
#include "openvpn.h"
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
#include "openvpn-gui-res.h"
|
||||
|
||||
extern struct options o;
|
||||
|
||||
void ViewLog(int config)
|
||||
{
|
||||
char filename[200];
|
||||
|
||||
extern char log_viewer[MAX_PATH];
|
||||
extern char log_dir[MAX_PATH];
|
||||
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
mysnprintf(filename, "%s \"%s\"", o.log_viewer, o.cnn[config].log_path);
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = 0;
|
||||
start_info.wShowWindow = SW_SHOWDEFAULT;
|
||||
start_info.hStdInput = NULL;
|
||||
start_info.hStdOutput = NULL;
|
||||
|
||||
if (!CreateProcess(NULL,
|
||||
filename, //commandline
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
CREATE_NEW_CONSOLE,
|
||||
NULL,
|
||||
o.log_dir, //start-up dir
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
/* could not start log viewer */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_START_LOG_VIEWER, o.log_viewer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EditConfig(int config)
|
||||
{
|
||||
char filename[200];
|
||||
|
||||
extern char config_dir[MAX_PATH];
|
||||
extern char editor[MAX_PATH];
|
||||
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
char command_line[256];
|
||||
|
||||
CLEAR (start_info);
|
||||
CLEAR (proc_info);
|
||||
CLEAR (sa);
|
||||
CLEAR (sd);
|
||||
|
||||
mysnprintf(filename, "%s \"%s\\%s\"", o.editor, o.cnn[config].config_dir, o.cnn[config].config_file);
|
||||
|
||||
/* fill in STARTUPINFO struct */
|
||||
GetStartupInfo(&start_info);
|
||||
start_info.cb = sizeof(start_info);
|
||||
start_info.dwFlags = 0;
|
||||
start_info.wShowWindow = SW_SHOWDEFAULT;
|
||||
start_info.hStdInput = NULL;
|
||||
start_info.hStdOutput = NULL;
|
||||
|
||||
if (!CreateProcess(NULL,
|
||||
filename, //commandline
|
||||
NULL,
|
||||
NULL,
|
||||
TRUE,
|
||||
CREATE_NEW_CONSOLE,
|
||||
NULL,
|
||||
o.cnn[config].config_dir, //start-up dir
|
||||
&start_info,
|
||||
&proc_info))
|
||||
{
|
||||
/* could not start editor */
|
||||
ShowLocalizedMsg(GUI_NAME, ERR_START_CONF_EDITOR, o.editor);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* OpenVPN-GUI -- A Windows GUI for OpenVPN.
|
||||
*
|
||||
* Copyright (C) 2004 Mathias Sundman <mathias@nilings.se>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (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
|
||||
*/
|
||||
|
||||
void ViewLog(int config);
|
||||
void EditConfig(int config);
|
Loading…
Reference in New Issue